diff --git a/CHANGES.txt b/CHANGES.txt
index 742b012..7ea01f7 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -7,6 +7,8 @@
     MAPREDUCE-2455. Remove deprecated JobTracker.State in favour of
     JobTrackerStatus. (tomwhite)
 
+    MAPREDUCE-2430. Remove mrunit contrib. (nigel via eli)
+
   NEW FEATURES
 
     MAPREDUCE-2543. [Gridmix] High-Ram feature emulation in Gridmix. (amarrk)
diff --git a/build.xml b/build.xml
index f0bd5ad..8474e79 100644
--- a/build.xml
+++ b/build.xml
@@ -2144,10 +2144,6 @@
                 output="${build.dir.eclipse-contrib-classes}/gridmix/main" />
         <source path="${contrib.dir}/gridmix/src/test"
                 output="${build.dir.eclipse-contrib-classes}/gridmix/test" />
-        <source path="${contrib.dir}/mrunit/src/java"
-                output="${build.dir.eclipse-contrib-classes}/mrunit/main" />
-        <source path="${contrib.dir}/mrunit/src/test"
-                output="${build.dir.eclipse-contrib-classes}/mrunit/test" />
         <source path="${contrib.dir}/mumak/src/java"
                 output="${build.dir.eclipse-contrib-classes}/mumak/main" />
         <source path="${contrib.dir}/mumak/src/test"
diff --git a/src/contrib/build.xml b/src/contrib/build.xml
index ddae8b9..1945c53 100644
--- a/src/contrib/build.xml
+++ b/src/contrib/build.xml
@@ -62,7 +62,6 @@
       <fileset dir="." includes="streaming/build.xml"/> 
       <fileset dir="." includes="fairscheduler/build.xml"/> 
       <fileset dir="." includes="capacity-scheduler/build.xml"/>  
-      <fileset dir="." includes="mrunit/build.xml"/> 
       <fileset dir="." includes="dynamic-scheduler/build.xml"/>
       <fileset dir="." includes="gridmix/build.xml"/>
       <fileset dir="." includes="vertica/build.xml"/>
diff --git a/src/contrib/mrunit/README.txt b/src/contrib/mrunit/README.txt
deleted file mode 100644
index 8850c4a..0000000
--- a/src/contrib/mrunit/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-MRUnit is a unit test driver for MapReduce programs for use with JUnit. See the overview
-in the Javadoc for more details.
diff --git a/src/contrib/mrunit/build.xml b/src/contrib/mrunit/build.xml
deleted file mode 100644
index 4985dd3..0000000
--- a/src/contrib/mrunit/build.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF 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.
--->
-
-<!-- 
-Before you can run these subtargets directly, you need 
-to call at top-level: ant deploy-contrib compile-core-test
--->
-<project name="mrunit" default="jar">
-
-  <import file="../build-contrib.xml"/>
-
-</project>
diff --git a/src/contrib/mrunit/doc/overview.html b/src/contrib/mrunit/doc/overview.html
deleted file mode 100644
index 620b59d..0000000
--- a/src/contrib/mrunit/doc/overview.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<body>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF 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.
--->
-<p>
-MRUnit is a library designed to allow easy testing of Mapper and Reducer
-classes using existing tools such as JUnit. MRUnit provides mock
-implementations of OutputCollector and Reporter for use in calling <tt>Mapper.map()</tt>
-and <tt>Reducer.reduce()</tt>, as well as a set of "driver" classes that manage
-delivery of key/value pair inputs to tasks, and comparison of actual task
-outputs with expected outputs.
-</p>
-
-<p>
-The primary advantage of MRUnit is that it allows you to test the outputs
-of individual maps and reduces, as well as the composition of the two, without
-needing to use the MiniMR cluster, or start a real MapReduce job in Hadoop,
-which are time-consuming processes.
-</p>
-
-<h3>Using MRUnit</h3>
-
-  MRUnit is designed to allow you to write ordinary JUnit test suites.
-
-<ul>
-<li> Include lib/mrunit-0.1.jar and lib/junit-4.4.jar on the classpath when
-    building and testing.</li>
-<li> The test methods for your Mapper implementation should use instances
-    of the <tt>MapDriver</tt>.</li>
-<li> The test methods for your Reducer implementation should use instances
-    of the <tt>ReduceDriver</tt>.</li>
-<li> MapReduce "jobs" consisting of a small number of inputs can be tested
-    with the <tt>MapReduceDriver</tt>. This supports a simple "shuffle" of outputs
-    to maintain the expected input delivery semantics to the reducer.</li>
-</ul>
-
-<p>
-A <tt>MapDriver</tt> or <tt>ReduceDriver</tt> instance is created for each test,
-as well as a fresh instance of your Mapper or Reducer. The driver is configured
-with the input keys and values, and expected output keys and values.
-</p>
-
-<p>
-  The <tt>run()</tt> method will execute the map or reduce, and returns the outputs
-retrieved from the OutputCollector.
-  The <tt>runTest()</tt> method will execute the map or reduce, and compares the
-actual outputs with the expected outputs, and returns true to indicate
-success and false on failure.
-  When expecting multiple outputs, the test drivers enforce that the order of
-the actual outputs is the same as the order in which outputs are configured
-(i.e., the order of calls to <tt>withOutput()</tt> or <tt>addOutput()</tt>).
-</p>
-
-<h3>Example</h3>
-
-<p>
-A brief test of Hadoop's <tt>IdentityMapper</tt> is presented here:
-</p>
-
-<div><tt><pre>
-import junit.framework.TestCase;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.lib.IdentityMapper;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestExample extends TestCase {
-
-  private Mapper<Text, Text, Text, Text> mapper;
-  private MapDriver<Text, Text, Text, Text> driver;
-
-  &#64;Before
-  public void setUp() {
-    mapper = new IdentityMapper<Text, Text>();
-    driver = new MapDriver<Text, Text, Text, Text>(mapper);
-  }
-
-  &#64;Test
-  public void testIdentityMapper() {
-    driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-  }
-}
-</pre></tt></div>
-
-<p>
-  This test first instantiates the Mapper and MapDriver. It configures
-an input (key, value) pair consisting of the strings "foo" and "bar",
-and expects these same values as output. It then calls <tt>runTest()</tt> to
-actually invoke the mapper, and compare the actual and expected outputs.
-The <tt>runTest()</tt> method will throw a RuntimeException if the output
-is not what it expects, which causes JUnit to mark the test case as failed.
-</p>
-
-<p>All <tt>with*()</tt> methods in MRUnit return a reference to <tt>this</tt>
-to allow them to be easily chained (e.g.,
-<tt>driver.withInput(a, b).withOutput(c, d).withOutput(d, e)...</tt>). These
-methods are analogous to the more conventional <tt>setInput()</tt>, <tt>addOutput()</tt>,
-etc. methods, which are also included.</p>
-
-<p>
-  Further examples of MRUnit usage can be seen in its own <tt>test/</tt> directory.
-The above example is in <tt>org.apache.hadoop.mrunit.TestExample</tt>. Further
-&quot;tests&quot; of the IdentityMapper are used to test the correctness of MRUnit
-itself; <tt>org.apache.hadoop.mrunit.TestMapDriver</tt> includes several tests of
-correctness for the MapDriver class; the <tt>testRunTest*()</tt> methods show
-how to apply the MapDriver to the IdentityMapper to confirm behavior surrounding
-both correct and incorrect input/output data sets. The <tt>testRunTest*()</tt> methods
-in <tt>org.apache.hadoop.mrunit.TestReduceDriver</tt> show how to apply the ReduceDriver
-test component to the LongSumReducer class.
-</p>
-
-</body>
diff --git a/src/contrib/mrunit/ivy.xml b/src/contrib/mrunit/ivy.xml
deleted file mode 100644
index 50faaf1..0000000
--- a/src/contrib/mrunit/ivy.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" ?>
-
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF 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.
--->
-
-<ivy-module version="1.0">
-  <info organisation="org.apache.hadoop" module="${ant.project.name}">
-    <license name="Apache 2.0"/>
-    <ivyauthor name="Apache Hadoop Team" url="http://hadoop.apache.org"/>
-    <description>
-        Apache Hadoop contrib
-    </description>
-  </info>
-  <configurations defaultconfmapping="default">
-    <!--these match the Maven configurations-->
-    <conf name="default" extends="master,runtime"/>
-    <conf name="master" description="contains the artifact but no dependencies"/>
-    <conf name="runtime" description="runtime but not the artifact" />
-
-    <conf name="common" visibility="private" 
-      description="artifacts needed to compile/test the application"/>
-    <conf name="test" visibility="private" extends="runtime"/>
-  </configurations>
-
-  <publications>
-    <!--get the artifact from our module name-->
-    <artifact conf="master"/>
-  </publications>
-  <dependencies>
-    <dependency org="org.apache.hadoop" name="hadoop-common" rev="${hadoop-common.version}" conf="common->default"/>
-    <dependency org="commons-logging" name="commons-logging" rev="${commons-logging.version}" conf="common->default"/>
-    <dependency org="log4j" name="log4j" rev="${log4j.version}" conf="common->master"/>
-    <dependency org="junit" name="junit" rev="${junit.version}" conf="common->master"/>
-    <dependency org="org.apache.hadoop" name="avro" rev="${avro.version}" conf="common->default">
-      <exclude module="ant"/>
-      <exclude module="jetty"/>
-      <exclude module="slf4j-simple"/>
-    </dependency>
-  </dependencies>
-
-</ivy-module>
diff --git a/src/contrib/mrunit/ivy/libraries.properties b/src/contrib/mrunit/ivy/libraries.properties
deleted file mode 100644
index 8a80dd8..0000000
--- a/src/contrib/mrunit/ivy/libraries.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-#   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.
-
-#This properties file lists the versions of the various artifacts used by streaming.
-#It drives ivy and the generation of a maven POM
-
-#Please list the dependencies name with version if they are different from the ones 
-#listed in the global libraries.properties file (in alphabetical order)
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapDriver.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapDriver.java
deleted file mode 100644
index 1b2bd69..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapDriver.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Counters;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mrunit.mock.MockOutputCollector;
-import org.apache.hadoop.mrunit.mock.MockReporter;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Mapper instance. You provide the input
- * key and value that should be sent to the Mapper, and outputs you expect to
- * be sent by the Mapper to the collector for those inputs. By calling
- * runTest(), the harness will deliver the input to the Mapper and will check
- * its outputs against the expected results. This is designed to handle a
- * single (k, v) -> (k, v)* case from the Mapper, representing a single unit
- * test. Multiple input (k, v) pairs should go in separate unit tests.
- */
-public class MapDriver<K1, V1, K2, V2> extends MapDriverBase<K1, V1, K2, V2> {
-
-  public static final Log LOG = LogFactory.getLog(MapDriver.class);
-
-  private Mapper<K1, V1, K2, V2> myMapper;
-  private Counters counters;
-
-  public MapDriver(final Mapper<K1, V1, K2, V2> m) {
-    myMapper = m;
-    counters = new Counters();
-  }
-
-  public MapDriver() {
-    counters = new Counters();
-  }
-
-  /** @return the counters used in this test */
-  public Counters getCounters() {
-    return counters;
-  }
-
-  /** Sets the counters object to use for this test.
-   * @param ctrs The counters object to use.
-   */
-  public void setCounters(final Counters ctrs) {
-    this.counters = ctrs;
-  }
-
-  /** Sets the counters to use and returns self for fluent style */
-  public MapDriver<K1, V1, K2, V2> withCounters(final Counters ctrs) {
-    setCounters(ctrs);
-    return this;
-  }
-
-  /**
-   * Set the Mapper instance to use with this test driver
-   *
-   * @param m the Mapper instance to use
-   */
-  public void setMapper(Mapper<K1, V1, K2, V2> m) {
-    myMapper = m;
-  }
-
-  /** Sets the Mapper instance to use and returns self for fluent style */
-  public MapDriver<K1, V1, K2, V2> withMapper(Mapper<K1, V1, K2, V2> m) {
-    setMapper(m);
-    return this;
-  }
-
-  /**
-   * @return the Mapper object being used by this test
-   */
-  public Mapper<K1, V1, K2, V2> getMapper() {
-    return myMapper;
-  }
-
-  /**
-   * Identical to setInputKey() but with fluent programming style
-   *
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInputKey(K1 key) {
-    setInputKey(key);
-    return this;
-  }
-
-  /**
-   * Identical to setInputValue() but with fluent programming style
-   *
-   * @param val
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInputValue(V1 val) {
-    setInputValue(val);
-    return this;
-  }
-
-  /**
-   * Identical to setInput() but returns self for fluent programming style
-   *
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInput(K1 key, V1 val) {
-    setInput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to setInput() but returns self for fluent programming style
-   *
-   * @param inputRecord
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInput(Pair<K1, V1> inputRecord) {
-    setInput(inputRecord);
-    return this;
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   *
-   * @param outputRecord
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withOutput(Pair<K2, V2> outputRecord) {
-    addOutput(outputRecord);
-    return this;
-  }
-
-  /**
-   * Functions like addOutput() but returns self for fluent programming
-   * style
-   *
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withOutput(K2 key, V2 val) {
-    addOutput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to setInputFromString, but with a fluent programming style
-   *
-   * @param input
-   *          A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInputFromString(String input) {
-    setInputFromString(input);
-    return this;
-  }
-
-  /**
-   * Identical to addOutputFromString, but with a fluent programming style
-   *
-   * @param output
-   *          A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withOutputFromString(String output) {
-    addOutputFromString(output);
-    return this;
-  }
-
-  @Override
-  public List<Pair<K2, V2>> run() throws IOException {
-    MockOutputCollector<K2, V2> outputCollector =
-      new MockOutputCollector<K2, V2>();
-    MockReporter reporter = new MockReporter(MockReporter.ReporterType.Mapper, getCounters());
-
-    myMapper.map(inputKey, inputVal, outputCollector, reporter);
-
-    return outputCollector.getOutputs();
-  }
-
-  @Override
-  public String toString() {
-    return "MapDriver (" + myMapper + ")";
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapDriverBase.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapDriverBase.java
deleted file mode 100644
index 3701cce..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapDriverBase.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mrunit.mock.MockOutputCollector;
-import org.apache.hadoop.mrunit.mock.MockReporter;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Mapper instance. You provide the input
- * key and value that should be sent to the Mapper, and outputs you expect to
- * be sent by the Mapper to the collector for those inputs. By calling
- * runTest(), the harness will deliver the input to the Mapper and will check
- * its outputs against the expected results. This is designed to handle a
- * single (k, v) -> (k, v)* case from the Mapper, representing a single unit
- * test. Multiple input (k, v) pairs should go in separate unit tests.
- */
-public abstract class MapDriverBase<K1, V1, K2, V2> extends TestDriver<K1, V1, K2, V2> {
-
-  public static final Log LOG = LogFactory.getLog(MapDriverBase.class);
-
-  protected K1 inputKey;
-  protected V1 inputVal;
-
-
-  /**
-   * Sets the input key to send to the mapper
-   *
-   */
-  public void setInputKey(K1 key) {
-    inputKey = key;
-  }
-
-  public K1 getInputKey() {
-    return inputKey;
-  }
-
-  /**
-   * Sets the input value to send to the mapper
-   *
-   * @param val
-   */
-  public void setInputValue(V1 val) {
-    inputVal = val;
-  }
-
-  public V1 getInputValue() {
-    return inputVal;
-  }
-
-  /**
-   * Sets the input to send to the mapper
-   *
-   */
-  public void setInput(K1 key, V1 val) {
-    setInputKey(key);
-    setInputValue(val);
-  }
-
-  /**
-   * Sets the input to send to the mapper
-   *
-   * @param inputRecord
-   *          a (key, val) pair
-   */
-  public void setInput(Pair<K1, V1> inputRecord) {
-    if (null != inputRecord) {
-      setInputKey(inputRecord.getFirst());
-      setInputValue(inputRecord.getSecond());
-    } else {
-      throw new IllegalArgumentException("null inputRecord in setInput()");
-    }
-  }
-
-  /**
-   * Adds an output (k, v) pair we expect from the Mapper
-   *
-   * @param outputRecord
-   *          The (k, v) pair to add
-   */
-  public void addOutput(Pair<K2, V2> outputRecord) {
-    if (null != outputRecord) {
-      expectedOutputs.add(outputRecord);
-    } else {
-      throw new IllegalArgumentException("Tried to add null outputRecord");
-    }
-  }
-
-  /**
-   * Adds a (k, v) pair we expect as output from the mapper
-   *
-   */
-  public void addOutput(K2 key, V2 val) {
-    addOutput(new Pair<K2, V2>(key, val));
-  }
-
-  /**
-   * Expects an input of the form "key \t val" Forces the Mapper input types
-   * to Text.
-   *
-   * @param input
-   *          A string of the form "key \t val".
-   */
-  public void setInputFromString(String input) {
-    if (null == input) {
-      throw new IllegalArgumentException("null input given to setInputFromString");
-    } else {
-      Pair<Text, Text> inputPair = parseTabbedPair(input);
-      if (null != inputPair) {
-        // I know this is not type-safe, but I don't know a better way to do
-        // this.
-        setInputKey((K1) inputPair.getFirst());
-        setInputValue((V1) inputPair.getSecond());
-      } else {
-        throw new IllegalArgumentException(
-            "Could not parse input pair in setInputFromString");
-      }
-    }
-  }
-
-  /**
-   * Expects an input of the form "key \t val" Forces the Mapper output types
-   * to Text.
-   *
-   * @param output
-   *          A string of the form "key \t val". Trims any whitespace.
-   */
-  public void addOutputFromString(String output) {
-    if (null == output) {
-      throw new IllegalArgumentException("null input given to setOutput");
-    } else {
-      Pair<Text, Text> outputPair = parseTabbedPair(output);
-      if (null != outputPair) {
-        // I know this is not type-safe, but I don't know a better way to do
-        // this.
-        addOutput((Pair<K2, V2>) outputPair);
-      } else {
-        throw new IllegalArgumentException("Could not parse output pair in setOutput");
-      }
-    }
-  }
-
-  public abstract List<Pair<K2, V2>> run() throws IOException;
-
-  @Override
-  public void runTest() throws RuntimeException {
-    String inputKeyStr = "(null)";
-    String inputValStr = "(null)";
-
-    if (null != inputKey) {
-      inputKeyStr = inputKey.toString();
-    }
-
-    if (null != inputVal) {
-      inputValStr = inputVal.toString();
-    }
-
-    LOG.debug("Mapping input (" + inputKeyStr + ", " + inputValStr + ")");
-
-    List<Pair<K2, V2>> outputs = null;
-
-    try {
-      outputs = run();
-      validate(outputs);
-    } catch (IOException ioe) {
-      LOG.error("IOException in mapper: " + ioe.toString());
-      LOG.debug("Setting success to false based on IOException");
-      throw new RuntimeException();
-    }
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapReduceDriver.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapReduceDriver.java
deleted file mode 100644
index 7a2b905..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapReduceDriver.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.io.RawComparator;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Counters;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.Reducer;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Mapper and a Reducer instance together
- * (along with an optional combiner).
- * You provide the input key and value that should be sent to the Mapper, and
- * outputs you expect to be sent by the Reducer to the collector for those
- * inputs. By calling runTest(), the harness will deliver the input to the
- * Mapper, feed the intermediate results to the Reducer (without checking
- * them), and will check the Reducer's outputs against the expected results.
- * This is designed to handle the (k, v)* -> (k, v)* case from the
- * Mapper/Reducer pair, representing a single unit test.
- *
- * If a combiner is specified, then it will be run exactly once after
- * the Mapper and before the Reducer.
- */
-public class MapReduceDriver<K1, V1, K2 extends Comparable, V2, K3, V3>
-    extends MapReduceDriverBase<K1, V1, K2, V2, K3, V3> {
-
-  public static final Log LOG = LogFactory.getLog(MapReduceDriver.class);
-
-  private Mapper<K1, V1, K2, V2> myMapper;
-  private Reducer<K2, V2, K3, V3> myReducer;
-  private Reducer<K2, V2, K2, V2> myCombiner;
-  private Counters counters;
-
-  public MapReduceDriver(final Mapper<K1, V1, K2, V2> m,
-                         final Reducer<K2, V2, K3, V3> r) {
-    myMapper = m;
-    myReducer = r;
-    counters = new Counters();
-  }
-
-  public MapReduceDriver(final Mapper<K1, V1, K2, V2> m,
-                         final Reducer<K2, V2, K3, V3> r,
-                         final Reducer<K2, V2, K2, V2> c) {
-    myMapper = m;
-    myReducer = r;
-    myCombiner = c;
-    counters = new Counters();
-  }
-
-  public MapReduceDriver() {
-    counters = new Counters();
-  }
-
-  /** @return the counters used in this test */
-  public Counters getCounters() {
-    return counters;
-  }
-
-  /** Sets the counters object to use for this test.
-   * @param ctrs The counters object to use.
-   */
-  public void setCounters(final Counters ctrs) {
-    this.counters = ctrs;
-  }
-
-  /** Sets the counters to use and returns self for fluent style */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withCounters(final Counters ctrs) {
-    setCounters(ctrs);
-    return this;
-  }
-
-  /** Set the Mapper instance to use with this test driver
-   * @param m the Mapper instance to use */
-  public void setMapper(Mapper<K1, V1, K2, V2> m) {
-    myMapper = m;
-  }
-
-  /** Sets the Mapper instance to use and returns self for fluent style */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withMapper(
-          Mapper<K1, V1, K2, V2> m) {
-    setMapper(m);
-    return this;
-  }
-
-  /**
-   * @return the Mapper object being used by this test
-   */
-  public Mapper<K1, V1, K2, V2> getMapper() {
-    return myMapper;
-  }
-
-  /**
-   * Sets the reducer object to use for this test
-   * @param r The reducer object to use
-   */
-  public void setReducer(Reducer<K2, V2, K3, V3> r) {
-    myReducer = r;
-  }
-
-  /**
-   * Identical to setReducer(), but with fluent programming style
-   * @param r The Reducer to use
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withReducer(
-          Reducer<K2, V2, K3, V3> r) {
-    setReducer(r);
-    return this;
-  }
-
-  /**
-   * @return the Reducer object being used for this test
-   */
-  public Reducer<K2, V2, K3, V3> getReducer() {
-    return myReducer;
-  }
-
-  /**
-   * Sets the reducer object to use as a combiner for this test
-   * @param c The combiner object to use
-   */
-  public void setCombiner(Reducer<K2, V2, K2, V2> c) {
-    myCombiner = c;
-  }
-
-  /**
-   * Identical to setCombiner(), but with fluent programming style
-   * @param c The Combiner to use
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withCombiner(
-          Reducer<K2, V2, K2, V2> c) {
-    setCombiner(c);
-    return this;
-  }
-
-  /**
-   * @return the Combiner object being used for this test
-   */
-  public Reducer<K2, V2, K2, V2> getCombiner() {
-    return myCombiner;
-  }
-
-  /**
-   * Identical to addInput() but returns self for fluent programming style
-   * @param key
-   * @param val
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withInput(K1 key, V1 val) {
-    addInput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to addInput() but returns self for fluent programming style
-   * @param input The (k, v) pair to add
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withInput(
-      Pair<K1, V1> input) {
-    addInput(input);
-    return this;
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   * @param outputRecord
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withOutput(
-          Pair<K3, V3> outputRecord) {
-    addOutput(outputRecord);
-    return this;
-  }
-
-  /**
-   * Functions like addOutput() but returns self for fluent programming style
-   * @param key
-   * @param val
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withOutput(K3 key, V3 val) {
-    addOutput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to addInputFromString, but with a fluent programming style
-   * @param input A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withInputFromString(String input) {
-    addInputFromString(input);
-    return this;
-  }
-
-  /**
-   * Identical to addOutputFromString, but with a fluent programming style
-   * @param output A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withOutputFromString(String output) {
-    addOutputFromString(output);
-    return this;
-  }
-
-  /** The private class to manage starting the reduce phase is used for type
-      genericity reasons. This class is used in the run() method. */
-  private class ReducePhaseRunner<OUTKEY, OUTVAL> {
-    private List<Pair<OUTKEY, OUTVAL>> runReduce(
-        List<Pair<K2, List<V2>>> inputs, Reducer<K2, V2, OUTKEY, OUTVAL> reducer)
-        throws IOException {
-
-      List<Pair<OUTKEY, OUTVAL>> reduceOutputs = new ArrayList<Pair<OUTKEY, OUTVAL>>();
-
-      for (Pair<K2, List<V2>> input : inputs) {
-        K2 inputKey = input.getFirst();
-        List<V2> inputValues = input.getSecond();
-        StringBuilder sb = new StringBuilder();
-        formatValueList(inputValues, sb);
-        LOG.debug("Reducing input (" + inputKey.toString() + ", "
-            + sb.toString() + ")");
-
-        reduceOutputs.addAll(new ReduceDriver<K2, V2, OUTKEY, OUTVAL>(reducer)
-                .withCounters(getCounters())
-                .withInputKey(inputKey)
-                .withInputValues(inputValues)
-                .run());
-      }
-
-      return reduceOutputs;
-    }
-  }
-
-  public List<Pair<K3, V3>> run() throws IOException {
-
-    List<Pair<K2, V2>> mapOutputs = new ArrayList<Pair<K2, V2>>();
-
-    // run map component
-    for (Pair<K1, V1> input : inputList) {
-      LOG.debug("Mapping input " + input.toString() + ")");
-
-      mapOutputs.addAll(new MapDriver<K1, V1, K2, V2>(myMapper).withInput(
-              input).withCounters(getCounters()).run());
-    }
-
-    if (myCombiner != null) {
-      // User has specified a combiner. Run this and replace the mapper outputs
-      // with the result of the combiner.
-      LOG.debug("Starting combine phase with combiner: " + myCombiner);
-      mapOutputs = new ReducePhaseRunner<K2, V2>().runReduce(shuffle(mapOutputs), myCombiner);
-    }
-
-    // Run the reduce phase.
-    LOG.debug("Starting reduce phase with reducer: " + myReducer);
-    return new ReducePhaseRunner<K3, V3>().runReduce(shuffle(mapOutputs), myReducer);
-  }
-
-  @Override
-  public String toString() {
-    return "MapReduceDriver (" + myMapper + ", " + myReducer + ")";
-  }
-  
-  /**
-   * Identical to {@link #setKeyGroupingComparator(RawComparator)}, but with a 
-   * fluent programming style 
-   * @param groupingComparator Comparator to use in the shuffle stage for key 
-   * grouping 
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withKeyGroupingComparator(
-      RawComparator<K2> groupingComparator) {
-    setKeyGroupingComparator(groupingComparator);
-    return this;
-  }
-  
-  /**
-   * Identical to {@link #setKeyOrderComparator(RawComparator)}, but with a 
-   * fluent programming style 
-   * @param orderComparator Comparator to use in the shuffle stage for key 
-   * value ordering 
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withKeyOrderComparator(
-      RawComparator<K2> orderComparator) {
-    setKeyOrderComparator(orderComparator);
-    return this;
-  }
-}
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapReduceDriverBase.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapReduceDriverBase.java
deleted file mode 100644
index 363cdb6..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/MapReduceDriverBase.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.TreeMap;
-import java.util.Map.Entry;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.io.RawComparator;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapreduce.Job;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Mapper and a Reducer instance together
- * You provide the input key and value that should be sent to the Mapper, and
- * outputs you expect to be sent by the Reducer to the collector for those
- * inputs. By calling runTest(), the harness will deliver the input to the
- * Mapper, feed the intermediate results to the Reducer (without checking
- * them), and will check the Reducer's outputs against the expected results.
- * This is designed to handle a single (k, v)* -> (k, v)* case from the
- * Mapper/Reducer pair, representing a single unit test.
- */
-public abstract class MapReduceDriverBase<K1, V1, K2 extends Comparable, V2, K3, V3>
-    extends TestDriver<K1, V1, K3, V3> {
-
-  public static final Log LOG = LogFactory.getLog(MapReduceDriverBase.class);
-
-  protected List<Pair<K1, V1>> inputList;
-  
-  /** Key group comparator */
-  protected Comparator<K2> keyGroupComparator;
-  
-  /** Key value order comparator */
-  protected Comparator<K2> keyValueOrderComparator;
-
-  public MapReduceDriverBase() {
-    inputList = new ArrayList<Pair<K1, V1>>();
-    
-    // create a simple comparator for key grouping and ordering
-    Comparator<K2> simpleComparator = new Comparator<K2>() {
-      @Override
-      public int compare(K2 o1, K2 o2) {
-        return o1.compareTo(o2);
-      }
-    };
-    
-    // assign simple key grouping and ordering comparator
-    keyGroupComparator = simpleComparator;
-    keyValueOrderComparator = null;
-  }
-
-  /**
-   * Adds an input to send to the mapper
-   * @param key
-   * @param val
-   */
-  public void addInput(K1 key, V1 val) {
-    inputList.add(new Pair<K1, V1>(key, val));
-  }
-
-  /**
-   * Adds an input to send to the Mapper
-   * @param input The (k, v) pair to add to the input list.
-   */
-  public void addInput(Pair<K1, V1> input) {
-    if (null == input) {
-      throw new IllegalArgumentException("Null input in addInput()");
-    }
-
-    inputList.add(input);
-  }
-
-  /**
-   * Adds an output (k, v) pair we expect from the Reducer
-   * @param outputRecord The (k, v) pair to add
-   */
-  public void addOutput(Pair<K3, V3> outputRecord) {
-    if (null != outputRecord) {
-      expectedOutputs.add(outputRecord);
-    } else {
-      throw new IllegalArgumentException("Tried to add null outputRecord");
-    }
-  }
-
-  /**
-   * Adds a (k, v) pair we expect as output from the Reducer
-   * @param key
-   * @param val
-   */
-  public void addOutput(K3 key, V3 val) {
-    addOutput(new Pair<K3, V3>(key, val));
-  }
-
-  /**
-   * Expects an input of the form "key \t val"
-   * Forces the Mapper input types to Text.
-   * @param input A string of the form "key \t val". Trims any whitespace.
-   */
-  public void addInputFromString(String input) {
-    if (null == input) {
-      throw new IllegalArgumentException("null input given to setInput");
-    } else {
-      Pair<Text, Text> inputPair = parseTabbedPair(input);
-      if (null != inputPair) {
-        // I know this is not type-safe, but I don't
-        // know a better way to do this.
-        addInput((Pair<K1, V1>) inputPair);
-      } else {
-        throw new IllegalArgumentException("Could not parse input pair in addInput");
-      }
-    }
-  }
-
-  /**
-   * Expects an input of the form "key \t val"
-   * Forces the Reducer output types to Text.
-   * @param output A string of the form "key \t val". Trims any whitespace.
-   */
-  public void addOutputFromString(String output) {
-    if (null == output) {
-      throw new IllegalArgumentException("null input given to setOutput");
-    } else {
-      Pair<Text, Text> outputPair = parseTabbedPair(output);
-      if (null != outputPair) {
-        // I know this is not type-safe,
-        // but I don't know a better way to do this.
-        addOutput((Pair<K3, V3>) outputPair);
-      } else {
-        throw new IllegalArgumentException(
-            "Could not parse output pair in setOutput");
-      }
-    }
-  }
-
-  public abstract List<Pair<K3, V3>> run() throws IOException;
-
-  @Override
-  public void runTest() throws RuntimeException {
-    List<Pair<K3, V3>> reduceOutputs = null;
-    boolean succeeded;
-
-    try {
-      reduceOutputs = run();
-      validate(reduceOutputs);
-    } catch (IOException ioe) {
-      LOG.error("IOException: " + ioe.toString());
-      LOG.debug("Setting success to false based on IOException");
-      throw new RuntimeException();
-    }
-  }
-
-  /** Take the outputs from the Mapper, combine all values for the
-   *  same key, and sort them by key.
-   * @param mapOutputs An unordered list of (key, val) pairs from the mapper
-   * @return the sorted list of (key, list(val))'s to present to the reducer
-   */
-  public List<Pair<K2, List<V2>>> shuffle(List<Pair<K2, V2>> mapOutputs) {
-    // step 1 - use the key group comparator to organise map outputs
-    final TreeMap<K2, List<Pair<K2,V2>>> groupedByKey = 
-        new TreeMap<K2, List<Pair<K2,V2>>>(keyGroupComparator);
-    
-    List<Pair<K2,V2>> groupedKeyList;
-    for (Pair<K2, V2> mapOutput : mapOutputs) {
-      groupedKeyList = groupedByKey.get(mapOutput.getFirst());
-      
-      if (groupedKeyList == null) {
-        groupedKeyList = new ArrayList<Pair<K2,V2>>();
-        groupedByKey.put(mapOutput.getFirst(), groupedKeyList);
-      }
-      
-      groupedKeyList.add(mapOutput);
-    }
-    
-    // step 2 - sort each key group using the key order comparator (if set)
-    Comparator<Pair<K2,V2>> pairKeyComparator = new Comparator<Pair<K2, V2>>() {
-      @Override
-      public int compare(Pair<K2, V2> o1, Pair<K2, V2> o2) {
-        return keyValueOrderComparator.compare(o1.getFirst(), o2.getFirst());
-      }
-    };
-    
-    // create shuffle stage output list
-    List<Pair<K2, List<V2>>> outputKeyValuesList = 
-        new ArrayList<Pair<K2,List<V2>>>();
-    
-    // populate output list
-    for (Entry<K2, List<Pair<K2, V2>>> groupedByKeyEntry : 
-          groupedByKey.entrySet()) {
-      if (keyValueOrderComparator != null) {
-        // sort the key/value pairs using the key order comparator (if set)
-        Collections.sort(groupedByKeyEntry.getValue(), pairKeyComparator);
-      }
-      
-      // create list to hold values for the grouped key
-      List<V2> valuesList = new ArrayList<V2>();
-      for (Pair<K2, V2> pair : groupedByKeyEntry.getValue()) {
-        valuesList.add(pair.getSecond());
-      }
-      
-      // add key and values to output list
-      outputKeyValuesList.add(
-          new Pair<K2,List<V2>>(groupedByKeyEntry.getKey(), valuesList));
-    }
-    
-    // return output list
-    return outputKeyValuesList;
-  }
-  
-  /**
-   * Set the key grouping comparator, similar to calling the following API 
-   * calls but passing a real instance rather than just the class:
-   * <UL>
-   * <LI>pre 0.20.1 API: {@link JobConf#setOutputValueGroupingComparator(Class)}
-   * <LI>0.20.1+ API: {@link Job#setGroupingComparatorClass(Class)}
-   * </UL>
-   * @param groupingComparator
-   */
-  public void setKeyGroupingComparator(
-        RawComparator<K2> groupingComparator) {
-    keyGroupComparator = groupingComparator;
-  }
-  
-  /**
-   * Set the key value order comparator, similar to calling the following API 
-   * calls but passing a real instance rather than just the class:
-   * <UL>
-   * <LI>pre 0.20.1 API: {@link JobConf#setOutputKeyComparatorClass(Class)}
-   * <LI>0.20.1+ API: {@link Job#setSortComparatorClass(Class)}
-   * </UL>
-   * @param orderComparator
-   */
-  public void setKeyOrderComparator(
-        RawComparator<K2> orderComparator) {
-    keyValueOrderComparator = orderComparator;
-  }
-}
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/PipelineMapReduceDriver.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/PipelineMapReduceDriver.java
deleted file mode 100644
index 3527940..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/PipelineMapReduceDriver.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Counters;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.Reducer;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a dataflow through a set of Mappers and
- * Reducers. You provide a set of (Mapper, Reducer) "jobs" that make up
- * a workflow, as well as a set of (key, value) pairs to pass in to the first
- * Mapper. You can also specify the outputs you expect to be sent to the final
- * Reducer in the pipeline.
- *
- * By calling runTest(), the harness will deliver the input to the first
- * Mapper, feed the intermediate results to the first Reducer (without checking
- * them), and proceed to forward this data along to subsequent Mapper/Reducer
- * jobs in the pipeline until the final Reducer. The last Reducer's outputs are
- * checked against the expected results.
- *
- * This is designed for slightly more complicated integration tests than the
- * MapReduceDriver, which is for smaller unit tests.
- *
- * (K1, V1) in the type signature refer to the types associated with the inputs
- * to the first Mapper. (K2, V2) refer to the types associated with the final
- * Reducer's output. No intermediate types are specified.
- */
-public class PipelineMapReduceDriver<K1, V1, K2, V2>
-    extends TestDriver<K1, V1, K2, V2> {
-
-  public static final Log LOG = LogFactory.getLog(PipelineMapReduceDriver.class);
-
-  private List<Pair<Mapper, Reducer>> mapReducePipeline;
-  private List<Pair<K1, V1>> inputList;
-  private Counters counters;
-
-  public PipelineMapReduceDriver(final List<Pair<Mapper, Reducer>> pipeline) {
-    this.mapReducePipeline = copyMapReduceList(pipeline);
-    this.inputList = new ArrayList<Pair<K1, V1>>();
-    this.counters = new Counters();
-  }
-
-  public PipelineMapReduceDriver() {
-    this.mapReducePipeline = new ArrayList<Pair<Mapper, Reducer>>();
-    this.inputList = new ArrayList<Pair<K1, V1>>();
-    this.counters = new Counters();
-  }
-
-  private List<Pair<Mapper, Reducer>> copyMapReduceList(List<Pair<Mapper, Reducer>> lst) {
-    List<Pair<Mapper, Reducer>> outList = new ArrayList<Pair<Mapper, Reducer>>();
-    for (Pair<Mapper, Reducer> p : lst) {
-      // Take advantage of the fact that Pair is immutable.
-      outList.add(p);
-    }
-
-    return outList;
-  }
-
-  /** @return the counters used in this test */
-  public Counters getCounters() {
-    return counters;
-  }
-
-  /** Sets the counters object to use for this test.
-   * @param ctrs The counters object to use.
-   */
-  public void setCounters(final Counters ctrs) {
-    this.counters = ctrs;
-  }
-
-  /** Sets the counters to use and returns self for fluent style */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withCounters(final Counters ctrs) {
-    setCounters(ctrs);
-    return this;
-  }
-
-
-  /** Add a Mapper and Reducer instance to the pipeline to use with this test driver
-   * @param m The Mapper instance to add to the pipeline
-   * @param r The Reducer instance to add to the pipeline
-   */
-  public void addMapReduce(Mapper m, Reducer r) {
-    Pair<Mapper, Reducer> p = new Pair<Mapper, Reducer>(m, r);
-    this.mapReducePipeline.add(p);
-  }
-
-  /** Add a Mapper and Reducer instance to the pipeline to use with this test driver
-   * @param p The Mapper and Reducer instances to add to the pipeline
-   */
-  public void addMapReduce(Pair<Mapper, Reducer> p) {
-    this.mapReducePipeline.add(p);
-  }
-
-  /** Add a Mapper and Reducer instance to the pipeline to use with this test driver
-   * using fluent style
-   * @param m The Mapper instance to use
-   * @param r The Reducer instance to use
-   */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withMapReduce(Mapper m, Reducer r) {
-    addMapReduce(m, r);
-    return this;
-  }
-
-  /** Add a Mapper and Reducer instance to the pipeline to use with this test driver
-   * using fluent style
-   * @param p The Mapper and Reducer instances to add to the pipeline
-   */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withMapReduce(Pair<Mapper, Reducer> p) {
-    addMapReduce(p);
-    return this;
-  }
-
-  /**
-   * @return A copy of the list of Mapper and Reducer objects under test
-   */
-  public List<Pair<Mapper, Reducer>> getMapReducePipeline() {
-    return copyMapReduceList(this.mapReducePipeline);
-  }
-
-  /**
-   * Adds an input to send to the mapper
-   * @param key
-   * @param val
-   */
-  public void addInput(K1 key, V1 val) {
-    inputList.add(new Pair<K1, V1>(key, val));
-  }
-
-  /**
-   * Identical to addInput() but returns self for fluent programming style
-   * @param key
-   * @param val
-   * @return this
-   */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withInput(K1 key, V1 val) {
-    addInput(key, val);
-    return this;
-  }
-
-  /**
-   * Adds an input to send to the Mapper
-   * @param input The (k, v) pair to add to the input list.
-   */
-  public void addInput(Pair<K1, V1> input) {
-    if (null == input) {
-      throw new IllegalArgumentException("Null input in addInput()");
-    }
-
-    inputList.add(input);
-  }
-
-  /**
-   * Identical to addInput() but returns self for fluent programming style
-   * @param input The (k, v) pair to add
-   * @return this
-   */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withInput(
-      Pair<K1, V1> input) {
-    addInput(input);
-    return this;
-  }
-
-  /**
-   * Adds an output (k, v) pair we expect from the Reducer
-   * @param outputRecord The (k, v) pair to add
-   */
-  public void addOutput(Pair<K2, V2> outputRecord) {
-    if (null != outputRecord) {
-      expectedOutputs.add(outputRecord);
-    } else {
-      throw new IllegalArgumentException("Tried to add null outputRecord");
-    }
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   * @param outputRecord
-   * @return this
-   */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withOutput(
-          Pair<K2, V2> outputRecord) {
-    addOutput(outputRecord);
-    return this;
-  }
-
-  /**
-   * Adds a (k, v) pair we expect as output from the Reducer
-   * @param key
-   * @param val
-   */
-  public void addOutput(K2 key, V2 val) {
-    addOutput(new Pair<K2, V2>(key, val));
-  }
-
-  /**
-   * Functions like addOutput() but returns self for fluent programming style
-   * @param key
-   * @param val
-   * @return this
-   */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withOutput(K2 key, V2 val) {
-    addOutput(key, val);
-    return this;
-  }
-
-  /**
-   * Expects an input of the form "key \t val"
-   * Forces the Mapper input types to Text.
-   * @param input A string of the form "key \t val". Trims any whitespace.
-   */
-  public void addInputFromString(String input) {
-    if (null == input) {
-      throw new IllegalArgumentException("null input given to setInput");
-    } else {
-      Pair<Text, Text> inputPair = parseTabbedPair(input);
-      if (null != inputPair) {
-        // I know this is not type-safe, but I don't
-        // know a better way to do this.
-        addInput((Pair<K1, V1>) inputPair);
-      } else {
-        throw new IllegalArgumentException("Could not parse input pair in addInput");
-      }
-    }
-  }
-
-  /**
-   * Identical to addInputFromString, but with a fluent programming style
-   * @param input A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withInputFromString(String input) {
-    addInputFromString(input);
-    return this;
-  }
-
-  /**
-   * Expects an input of the form "key \t val"
-   * Forces the Reducer output types to Text.
-   * @param output A string of the form "key \t val". Trims any whitespace.
-   */
-  public void addOutputFromString(String output) {
-    if (null == output) {
-      throw new IllegalArgumentException("null input given to setOutput");
-    } else {
-      Pair<Text, Text> outputPair = parseTabbedPair(output);
-      if (null != outputPair) {
-        // I know this is not type-safe,
-        // but I don't know a better way to do this.
-        addOutput((Pair<K2, V2>) outputPair);
-      } else {
-        throw new IllegalArgumentException(
-            "Could not parse output pair in setOutput");
-      }
-    }
-  }
-
-  /**
-   * Identical to addOutputFromString, but with a fluent programming style
-   * @param output A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public PipelineMapReduceDriver<K1, V1, K2, V2> withOutputFromString(String output) {
-    addOutputFromString(output);
-    return this;
-  }
-
-  public List<Pair<K2, V2>> run() throws IOException {
-    // inputs starts with the user-provided inputs.
-    List inputs = this.inputList;
-
-    if (mapReducePipeline.size() == 0) {
-      LOG.warn("No Mapper or Reducer instances in pipeline; this is a trivial test.");
-    }
-
-    if (inputs.size() == 0) {
-      LOG.warn("No inputs configured to send to MapReduce pipeline; this is a trivial test.");
-    }
-
-    for (Pair<Mapper, Reducer> job : mapReducePipeline) {
-      // Create a MapReduceDriver to run this phase of the pipeline.
-      MapReduceDriver mrDriver = new MapReduceDriver(job.getFirst(), job.getSecond());
-
-      mrDriver.setCounters(getCounters());
-
-      // Add the inputs from the user, or from the previous stage of the pipeline.
-      for (Object input : inputs) {
-        mrDriver.addInput((Pair) input);
-      }
-
-      // Run the MapReduce "job". The output of this job becomes
-      // the input to the next job.
-      inputs = mrDriver.run();
-    }
-
-    // The last list of values stored in "inputs" is actually the outputs.
-    // Unfortunately, due to the variable-length list of MR passes the user 
-    // can test, this is not type-safe.
-    return (List<Pair<K2, V2>>) inputs;
-  }
-
-  @Override
-  public void runTest() throws RuntimeException {
-    List<Pair<K2, V2>> outputs = null;
-    boolean succeeded;
-
-    try {
-      outputs = run();
-      validate(outputs);
-    } catch (IOException ioe) {
-      LOG.error("IOException: " + ioe.toString());
-      LOG.debug("Setting success to false based on IOException");
-      throw new RuntimeException();
-    }
-  }
-}
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/ReduceDriver.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/ReduceDriver.java
deleted file mode 100644
index e017725..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/ReduceDriver.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Counters;
-import org.apache.hadoop.mapred.Reducer;
-import org.apache.hadoop.mrunit.mock.MockOutputCollector;
-import org.apache.hadoop.mrunit.mock.MockReporter;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Reducer instance. You provide a key and a
- * set of intermediate values for that key that represent inputs that should
- * be sent to the Reducer (as if they came from a Mapper), and outputs you
- * expect to be sent by the Reducer to the collector. By calling runTest(),
- * the harness will deliver the input to the Reducer and will check its
- * outputs against the expected results. This is designed to handle a single
- * (k, v*) -> (k, v)* case from the Reducer, representing a single unit test.
- * Multiple input (k, v*) sets should go in separate unit tests.
- */
-public class ReduceDriver<K1, V1, K2, V2> extends ReduceDriverBase<K1, V1, K2, V2> {
-
-  public static final Log LOG = LogFactory.getLog(ReduceDriver.class);
-
-  private Reducer<K1, V1, K2, V2> myReducer;
-  private Counters counters;
-
-  public ReduceDriver(final Reducer<K1, V1, K2, V2> r) {
-    myReducer = r;
-    counters = new Counters();
-  }
-
-  public ReduceDriver() {
-    counters = new Counters();
-  }
-
-  /** @return the counters used in this test */
-  public Counters getCounters() {
-    return counters;
-  }
-
-  /** Sets the counters object to use for this test.
-   * @param ctrs The counters object to use.
-   */
-  public void setCounters(final Counters ctrs) {
-    this.counters = ctrs;
-  }
-
-  /** Sets the counters to use and returns self for fluent style */
-  public ReduceDriver<K1, V1, K2, V2> withCounters(final Counters ctrs) {
-    setCounters(ctrs);
-    return this;
-  }
-
-
-  /**
-   * Sets the reducer object to use for this test
-   *
-   * @param r
-   *          The reducer object to use
-   */
-  public void setReducer(Reducer<K1, V1, K2, V2> r) {
-    myReducer = r;
-  }
-
-  /**
-   * Identical to setReducer(), but with fluent programming style
-   *
-   * @param r
-   *          The Reducer to use
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withReducer(Reducer<K1, V1, K2, V2> r) {
-    setReducer(r);
-    return this;
-  }
-
-  public Reducer<K1, V1, K2, V2> getReducer() {
-    return myReducer;
-  }
-
-  /**
-   * Identical to setInputKey() but with fluent programming style
-   *
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInputKey(K1 key) {
-    setInputKey(key);
-    return this;
-  }
-
-  /**
-   * Identical to addInputValue() but with fluent programming style
-   *
-   * @param val
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInputValue(V1 val) {
-    addInputValue(val);
-    return this;
-  }
-
-  /**
-   * Identical to addInputValues() but with fluent programming style
-   *
-   * @param values
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInputValues(List<V1> values) {
-    addInputValues(values);
-    return this;
-  }
-
-  /**
-   * Identical to setInput() but returns self for fluent programming style
-   *
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInput(K1 key, List<V1> values) {
-    setInput(key, values);
-    return this;
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   *
-   * @param outputRecord
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withOutput(Pair<K2, V2> outputRecord) {
-    addOutput(outputRecord);
-    return this;
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   *
-   * @param key The key part of a (k, v) pair to add
-   * @param val The val part of a (k, v) pair to add
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withOutput(K2 key, V2 val) {
-    addOutput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to setInput, but with a fluent programming style
-   *
-   * @param input
-   *          A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInputFromString(String input) {
-    setInputFromString(input);
-    return this;
-  }
-
-  /**
-   * Identical to addOutput, but with a fluent programming style
-   *
-   * @param output
-   *          A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withOutputFromString(String output) {
-    addOutputFromString(output);
-    return this;
-  }
-
-  @Override
-  public List<Pair<K2, V2>> run() throws IOException {
-    MockOutputCollector<K2, V2> outputCollector =
-      new MockOutputCollector<K2, V2>();
-    MockReporter reporter = new MockReporter(MockReporter.ReporterType.Reducer, getCounters());
-
-    myReducer.reduce(inputKey, inputValues.iterator(), outputCollector,
-            reporter);
-
-    List<Pair<K2, V2>> outputs = outputCollector.getOutputs();
-    return outputs;
-  }
-
-  @Override
-  public String toString() {
-    return "ReduceDriver (" + myReducer + ")";
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/ReduceDriverBase.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/ReduceDriverBase.java
deleted file mode 100644
index dc77a0d..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/ReduceDriverBase.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mrunit.mock.MockOutputCollector;
-import org.apache.hadoop.mrunit.mock.MockReporter;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Reducer instance. You provide a key and a
- * set of intermediate values for that key that represent inputs that should
- * be sent to the Reducer (as if they came from a Mapper), and outputs you
- * expect to be sent by the Reducer to the collector. By calling runTest(),
- * the harness will deliver the input to the Reducer and will check its
- * outputs against the expected results. This is designed to handle a single
- * (k, v*) -> (k, v)* case from the Reducer, representing a single unit test.
- * Multiple input (k, v*) sets should go in separate unit tests.
- */
-public abstract class ReduceDriverBase<K1, V1, K2, V2> extends TestDriver<K1, V1, K2, V2> {
-
-  protected K1 inputKey;
-  protected List<V1> inputValues;
-
-  public ReduceDriverBase() {
-    inputValues = new ArrayList<V1>();
-  }
-
-  /**
-   * Sets the input key to send to the Reducer
-   *
-   */
-  public void setInputKey(K1 key) {
-    inputKey = key;
-  }
-
-  /**
-   * adds an input value to send to the reducer
-   *
-   * @param val
-   */
-  public void addInputValue(V1 val) {
-    inputValues.add(val);
-  }
-
-  /**
-   * Sets the input values to send to the reducer; overwrites existing ones
-   *
-   * @param values
-   */
-  public void setInputValues(List<V1> values) {
-    inputValues.clear();
-    inputValues.addAll(values);
-  }
-
-  /**
-   * Adds a set of input values to send to the reducer
-   *
-   * @param values
-   */
-  public void addInputValues(List<V1> values) {
-    inputValues.addAll(values);
-  }
-
-  /**
-   * Sets the input to send to the reducer
-   *
-   * @param values
-   */
-  public void setInput(K1 key, List<V1> values) {
-    setInputKey(key);
-    setInputValues(values);
-  }
-
-  /**
-   * Adds an output (k, v) pair we expect from the Reducer
-   *
-   * @param outputRecord
-   *          The (k, v) pair to add
-   */
-  public void addOutput(Pair<K2, V2> outputRecord) {
-    if (null != outputRecord) {
-      expectedOutputs.add(outputRecord);
-    } else {
-      throw new IllegalArgumentException("Tried to add null outputRecord");
-    }
-  }
-
-  /**
-   * Adds an output (k, v) pair we expect from the Reducer
-   *
-   * @param key The key part of a (k, v) pair to add
-   * @param val The val part of a (k, v) pair to add
-   */
-  public void addOutput(K2 key, V2 val) {
-    addOutput(new Pair<K2, V2>(key, val));
-  }
-
-  /**
-   * Expects an input of the form "key \t val, val, val..." Forces the Reducer
-   * input types to Text.
-   *
-   * @param input
-   *          A string of the form "key \t val,val,val". Trims any whitespace.
-   */
-  public void setInputFromString(String input) {
-    if (null == input) {
-      throw new IllegalArgumentException("null input given to setInputFromString");
-    } else {
-      Pair<Text, Text> inputPair = parseTabbedPair(input);
-      if (null != inputPair) {
-        // I know this is not type-safe, but I don't know a better way to do
-        // this.
-        setInputKey((K1) inputPair.getFirst());
-        setInputValues((List<V1>) parseCommaDelimitedList(inputPair.getSecond()
-                .toString()));
-      } else {
-        throw new IllegalArgumentException(
-            "Could not parse input pair in setInputFromString");
-      }
-    }
-  }
-
-  /**
-   * Expects an input of the form "key \t val" Forces the Reducer output types
-   * to Text.
-   *
-   * @param output
-   *          A string of the form "key \t val". Trims any whitespace.
-   */
-  public void addOutputFromString(String output) {
-    if (null == output) {
-      throw new IllegalArgumentException("null input given to setOutput");
-    } else {
-      Pair<Text, Text> outputPair = parseTabbedPair(output);
-      if (null != outputPair) {
-        // I know this is not type-safe, but I don't know a better way to do
-        // this.
-        addOutput((Pair<K2, V2>) outputPair);
-      } else {
-        throw new IllegalArgumentException("Could not parse output pair in setOutput");
-      }
-    }
-  }
-
-  public abstract List<Pair<K2, V2>> run() throws IOException;
-
-  @Override
-  public void runTest() throws RuntimeException {
-
-    String inputKeyStr = "(null)";
-
-    if (null != inputKey) {
-      inputKeyStr = inputKey.toString();
-    }
-
-    StringBuilder sb = new StringBuilder();
-    formatValueList(inputValues, sb);
-
-    LOG.debug("Reducing input (" + inputKeyStr + ", " + sb.toString() + ")");
-
-    List<Pair<K2, V2>> outputs = null;
-    try {
-      outputs = run();
-      validate(outputs);
-    } catch (IOException ioe) {
-      LOG.error("IOException in reducer: " + ioe.toString());
-      LOG.debug("Setting success to false based on IOException");
-      throw new RuntimeException();
-    }
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/TestDriver.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/TestDriver.java
deleted file mode 100644
index 3a9c9d5..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/TestDriver.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mrunit.types.Pair;
-
-public abstract class TestDriver<K1, V1, K2, V2> {
-
-  public static final Log LOG = LogFactory.getLog(TestDriver.class);
-
-  protected List<Pair<K2, V2>> expectedOutputs;
-  
-  protected Configuration configuration;
-
-  public TestDriver() {
-    expectedOutputs = new ArrayList<Pair<K2, V2>>();
-    configuration = new Configuration();
-  }
-
-  /**
-   * @return the list of (k, v) pairs expected as output from this driver
-   */
-  public List<Pair<K2, V2>> getExpectedOutputs() {
-    return expectedOutputs;
-  }
-
-  /**
-   * Clears the list of outputs expected from this driver
-   */
-  public void resetOutput() {
-    expectedOutputs.clear();
-  }
-
-  /**
-   * Runs the test but returns the result set instead of validating it
-   * (ignores any addOutput(), etc calls made before this)
-   * @return the list of (k, v) pairs returned as output from the test
-   */
-  public abstract List<Pair<K2, V2>> run() throws IOException;
-
-  /**
-   * Runs the test and validates the results
-   * @return void if the tests passed
-   * @throws RuntimeException if they don't
-   * *
-   */
-  public abstract void runTest() throws RuntimeException;
-
-  /**
-   * Split "key \t val" into Pair(Text(key), Text(val))
-   * @param tabSeparatedPair
-   */
-  public static Pair<Text, Text> parseTabbedPair(String tabSeparatedPair) {
-
-    String key, val;
-
-    if (null == tabSeparatedPair) {
-      return null;
-    }
-
-    int split = tabSeparatedPair.indexOf('\t');
-    if (-1 == split) {
-      return null;
-    }
-
-    key = tabSeparatedPair.substring(0, split);
-    val = tabSeparatedPair.substring(split + 1);
-
-    return new Pair<Text, Text>(new Text(key), new Text(val));
-  }
-
-  /**
-   * Split "val,val,val,val..." into a List of Text(val) objects.
-   * @param commaDelimList A list of values separated by commas
-   */
-  protected static List<Text> parseCommaDelimitedList(String commaDelimList) {
-    ArrayList<Text> outList = new ArrayList<Text>();
-
-    if (null == commaDelimList) {
-      return null;
-    }
-
-    int len = commaDelimList.length();
-    int curPos = 0;
-    int curComma = commaDelimList.indexOf(',');
-    if (curComma == -1) {
-      curComma = len;
-    }
-
-    while (curPos < len) {
-      outList.add(new Text(
-              commaDelimList.substring(curPos, curComma).trim()));
-      curPos = curComma + 1;
-      curComma = commaDelimList.indexOf(',', curPos);
-      if (curComma == -1) {
-        curComma = len;
-      }
-    }
-
-    return outList;
-  }
-
-  /**
-   * check the outputs against the expected inputs in record
-   * @param outputs The actual output (k, v) pairs from the Mapper
-   * @return void if they all pass
-   * @throws RuntimeException if they don't
-   */
-  protected void validate(List<Pair<K2, V2>> outputs) throws RuntimeException {
-
-    boolean success = true;
-
-    // were we supposed to get output in the first place?
-    // return false if we don't.
-    if (expectedOutputs.size() == 0 && outputs.size() > 0) {
-      LOG.error("Expected no outputs; got " + outputs.size() + " outputs.");
-      success = false;
-    }
-
-    // make sure all actual outputs are in the expected set,
-    // and at the proper position.
-    for (int i = 0; i < outputs.size(); i++) {
-      Pair<K2, V2> actual = outputs.get(i);
-      success = lookupExpectedValue(actual, i) && success;
-    }
-
-    // make sure all expected outputs were accounted for.
-    if (expectedOutputs.size() != outputs.size() || !success) {
-      // something is unaccounted for. Figure out what.
-
-      ArrayList<Pair<K2, V2>> actuals = new ArrayList<Pair<K2, V2>>();
-      actuals.addAll(outputs);
-
-      for (int i = 0; i < expectedOutputs.size(); i++) {
-        Pair<K2, V2> expected = expectedOutputs.get(i);
-
-        boolean found = false;
-        for (int j = 0; j < actuals.size() && !found; j++) {
-          Pair<K2, V2> actual = actuals.get(j);
-
-          if (actual.equals(expected)) {
-            // don't match against this actual output again
-            actuals.remove(j);
-            found = true;
-          }
-        }
-
-        if (!found) {
-          String expectedStr = "(null)";
-          if (null != expected) {
-            expectedStr = expected.toString();
-          }
-
-          LOG.error("Missing expected output " + expectedStr + " at position "
-              + i);
-        }
-      }
-
-      success = false;
-    }
-
-    if (!success) {
-      throw new RuntimeException();
-    }
-  }
-
-  /**
-   * Part of the validation system.
-   * @param actualVal A (k, v) pair we got from the Mapper
-   * @param actualPos The position of this pair in the actual output
-   * @return true if the expected val at 'actualPos' in the expected
-   *              list equals actualVal
-   */
-  private boolean lookupExpectedValue(Pair<K2, V2> actualVal, int actualPos) {
-
-    // first: Do we have the success condition?
-    if (expectedOutputs.size() > actualPos
-            && expectedOutputs.get(actualPos).equals(actualVal)) {
-      LOG.debug("Matched expected output " + actualVal.toString()
-          + " at position " + actualPos);
-      return true;
-    }
-
-    // second: can we find this output somewhere else in
-    // the expected list?
-    boolean foundSomewhere = false;
-
-    for (int i = 0; i < expectedOutputs.size() && !foundSomewhere; i++) {
-      Pair<K2, V2> expected = expectedOutputs.get(i);
-
-      if (expected.equals(actualVal)) {
-        LOG.error("Matched expected output "
-                + actualVal.toString() + " but at incorrect position "
-                + actualPos + " (expected position " + i + ")");
-        foundSomewhere = true;
-      }
-    }
-
-    if (!foundSomewhere) {
-      LOG.error("Received unexpected output " + actualVal.toString());
-    }
-
-    return false;
-  }
-
-  protected static void formatValueList(List values, StringBuilder sb) {
-    sb.append("(");
-
-    if (null != values) {
-      boolean first = true;
-
-      for (Object val : values) {
-        if (!first) {
-          sb.append(", ");
-        }
-
-        first = false;
-        sb.append(val.toString());
-      }
-    }
-
-    sb.append(")");
-  }
-
-  /** 
-   * @return The configuration object that will given to the mapper and/or 
-   *         reducer associated with the driver (new API only)
-   */
-  public Configuration getConfiguration() {
-    return configuration;
-  }
-  
-  /**
-   * @param configuration The configuration object that will given to the 
-   *        mapper and/or reducer associated with the driver (new API only)
-   */
-  public void setConfiguration(Configuration configuration) {
-    this.configuration = configuration;
-  }
-}
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/MapDriver.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/MapDriver.java
deleted file mode 100644
index 84fbed1..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/MapDriver.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.mapreduce.Counters;
-import org.apache.hadoop.mapreduce.Mapper;
-import org.apache.hadoop.mapreduce.lib.map.WrappedMapper;
-import org.apache.hadoop.mrunit.MapDriverBase;
-import org.apache.hadoop.mrunit.mapreduce.mock.MockMapContext;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Mapper instance. You provide the input
- * key and value that should be sent to the Mapper, and outputs you expect to
- * be sent by the Mapper to the collector for those inputs. By calling
- * runTest(), the harness will deliver the input to the Mapper and will check
- * its outputs against the expected results. This is designed to handle a
- * single (k, v) -> (k, v)* case from the Mapper, representing a single unit
- * test. Multiple input (k, v) pairs should go in separate unit tests.
- */
-public class MapDriver<K1, V1, K2, V2> extends MapDriverBase<K1, V1, K2, V2> {
-
-  public static final Log LOG = LogFactory.getLog(MapDriver.class);
-
-  private Mapper<K1, V1, K2, V2> myMapper;
-  private Counters counters;
-
-  public MapDriver(final Mapper<K1, V1, K2, V2> m) {
-    myMapper = m;
-    counters = new Counters();
-  }
-
-  public MapDriver() {
-    counters = new Counters();
-  }
-
-
-  /**
-   * Set the Mapper instance to use with this test driver
-   *
-   * @param m the Mapper instance to use
-   */
-  public void setMapper(Mapper<K1, V1, K2, V2> m) {
-    myMapper = m;
-  }
-
-  /** Sets the Mapper instance to use and returns self for fluent style */
-  public MapDriver<K1, V1, K2, V2> withMapper(Mapper<K1, V1, K2, V2> m) {
-    setMapper(m);
-    return this;
-  }
-
-  /**
-   * @return the Mapper object being used by this test
-   */
-  public Mapper<K1, V1, K2, V2> getMapper() {
-    return myMapper;
-  }
-
-  /** @return the counters used in this test */
-  public Counters getCounters() {
-    return counters;
-  }
-
-  /** Sets the counters object to use for this test.
-   * @param ctrs The counters object to use.
-   */
-  public void setCounters(final Counters ctrs) {
-    this.counters = ctrs;
-  }
-
-  /** Sets the counters to use and returns self for fluent style */
-  public MapDriver<K1, V1, K2, V2> withCounters(final Counters ctrs) {
-    setCounters(ctrs);
-    return this;
-  }
-
-  /**
-   * Identical to setInputKey() but with fluent programming style
-   *
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInputKey(K1 key) {
-    setInputKey(key);
-    return this;
-  }
-
-  /**
-   * Identical to setInputValue() but with fluent programming style
-   *
-   * @param val
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInputValue(V1 val) {
-    setInputValue(val);
-    return this;
-  }
-
-  /**
-   * Identical to setInput() but returns self for fluent programming style
-   *
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInput(K1 key, V1 val) {
-    setInput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to setInput() but returns self for fluent programming style
-   *
-   * @param inputRecord
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInput(Pair<K1, V1> inputRecord) {
-    setInput(inputRecord);
-    return this;
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   *
-   * @param outputRecord
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withOutput(Pair<K2, V2> outputRecord) {
-    addOutput(outputRecord);
-    return this;
-  }
-
-  /**
-   * Functions like addOutput() but returns self for fluent programming
-   * style
-   *
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withOutput(K2 key, V2 val) {
-    addOutput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to setInputFromString, but with a fluent programming style
-   *
-   * @param input
-   *          A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withInputFromString(String input) {
-    setInputFromString(input);
-    return this;
-  }
-
-  /**
-   * Identical to addOutputFromString, but with a fluent programming style
-   *
-   * @param output
-   *          A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public MapDriver<K1, V1, K2, V2> withOutputFromString(String output) {
-    addOutputFromString(output);
-    return this;
-  }
-
-  @Override
-  public List<Pair<K2, V2>> run() throws IOException {
-    List<Pair<K1, V1>> inputs = new ArrayList<Pair<K1, V1>>();
-    inputs.add(new Pair<K1, V1>(inputKey, inputVal));
-
-    try {
-      MockMapContext<K1, V1, K2, V2> context =
-        new MockMapContext<K1, V1, K2, V2>(configuration, inputs, getCounters());
-
-      myMapper.run(new WrappedMapper<K1, V1, K2, V2>().getMapContext(context));
-      return context.getOutputs();
-    } catch (InterruptedException ie) {
-      throw new IOException(ie);
-    }
-  }
-
-  @Override
-  public String toString() {
-    return "MapDriver (0.20+) (" + myMapper + ")";
-  }
-  
-  /** 
-   * @param configuration The configuration object that will given to the mapper
-   *        associated with the driver
-   * @return this object for fluent coding
-   */
-  public MapDriver<K1, V1, K2, V2> withConfiguration(Configuration configuration) {
-    setConfiguration(configuration);
-	  return this;
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/MapReduceDriver.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/MapReduceDriver.java
deleted file mode 100644
index f4a748d..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/MapReduceDriver.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.io.RawComparator;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapreduce.Counters;
-import org.apache.hadoop.mapreduce.Mapper;
-import org.apache.hadoop.mapreduce.Reducer;
-import org.apache.hadoop.mrunit.MapReduceDriverBase;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Mapper and a Reducer instance together
- * You provide the input key and value that should be sent to the Mapper, and
- * outputs you expect to be sent by the Reducer to the collector for those
- * inputs. By calling runTest(), the harness will deliver the input to the
- * Mapper, feed the intermediate results to the Reducer (without checking
- * them), and will check the Reducer's outputs against the expected results.
- * This is designed to handle a single (k, v)* -> (k, v)* case from the
- * Mapper/Reducer pair, representing a single unit test.
- */
-public class MapReduceDriver<K1, V1, K2 extends Comparable, V2, K3, V3>
-    extends MapReduceDriverBase<K1, V1, K2, V2, K3, V3> {
-
-  public static final Log LOG = LogFactory.getLog(MapReduceDriver.class);
-
-  private Mapper<K1, V1, K2, V2> myMapper;
-  private Reducer<K2, V2, K3, V3> myReducer;
-  private Counters counters;
-
-  public MapReduceDriver(final Mapper<K1, V1, K2, V2> m,
-                         final Reducer<K2, V2, K3, V3> r) {
-    myMapper = m;
-    myReducer = r;
-    counters = new Counters();
-  }
-
-  public MapReduceDriver() {
-    counters = new Counters();
-  }
-
-  /** Set the Mapper instance to use with this test driver
-   * @param m the Mapper instance to use */
-  public void setMapper(Mapper<K1, V1, K2, V2> m) {
-    myMapper = m;
-  }
-
-  /** Sets the Mapper instance to use and returns self for fluent style */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withMapper(
-          Mapper<K1, V1, K2, V2> m) {
-    setMapper(m);
-    return this;
-  }
-
-  /**
-   * @return the Mapper object being used by this test
-   */
-  public Mapper<K1, V1, K2, V2> getMapper() {
-    return myMapper;
-  }
-
-  /**
-   * Sets the reducer object to use for this test
-   * @param r The reducer object to use
-   */
-  public void setReducer(Reducer<K2, V2, K3, V3> r) {
-    myReducer = r;
-  }
-
-  /**
-   * Identical to setReducer(), but with fluent programming style
-   * @param r The Reducer to use
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withReducer(
-          Reducer<K2, V2, K3, V3> r) {
-    setReducer(r);
-    return this;
-  }
-
-  /**
-   * @return the Reducer object being used for this test
-   */
-  public Reducer<K2, V2, K3, V3> getReducer() {
-    return myReducer;
-  }
-
-  /** @return the counters used in this test */
-  public Counters getCounters() {
-    return counters;
-  }
-
-  /** Sets the counters object to use for this test.
-   * @param ctrs The counters object to use.
-   */
-  public void setCounters(final Counters ctrs) {
-    this.counters = ctrs;
-  }
-
-  /** Sets the counters to use and returns self for fluent style */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withCounters(final Counters ctrs) {
-    setCounters(ctrs);
-    return this;
-  }
-
-  /**
-   * Identical to addInput() but returns self for fluent programming style
-   * @param key
-   * @param val
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withInput(K1 key, V1 val) {
-    addInput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to addInput() but returns self for fluent programming style
-   * @param input The (k, v) pair to add
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withInput(
-      Pair<K1, V1> input) {
-    addInput(input);
-    return this;
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   * @param outputRecord
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withOutput(
-          Pair<K3, V3> outputRecord) {
-    addOutput(outputRecord);
-    return this;
-  }
-
-  /**
-   * Functions like addOutput() but returns self for fluent programming style
-   * @param key
-   * @param val
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withOutput(K3 key, V3 val) {
-    addOutput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to addInputFromString, but with a fluent programming style
-   * @param input A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withInputFromString(String input) {
-    addInputFromString(input);
-    return this;
-  }
-
-  /**
-   * Identical to addOutputFromString, but with a fluent programming style
-   * @param output A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withOutputFromString(String output) {
-    addOutputFromString(output);
-    return this;
-  }
-
-  public List<Pair<K3, V3>> run() throws IOException {
-
-    List<Pair<K2, V2>> mapOutputs = new ArrayList<Pair<K2, V2>>();
-
-    // run map component
-    for (Pair<K1, V1> input : inputList) {
-      LOG.debug("Mapping input " + input.toString() + ")");
-
-      mapOutputs.addAll(new MapDriver<K1, V1, K2, V2>(myMapper).withInput(
-              input).withCounters(getCounters()).withConfiguration(configuration).run());
-    }
-
-    List<Pair<K2, List<V2>>> reduceInputs = shuffle(mapOutputs);
-    List<Pair<K3, V3>> reduceOutputs = new ArrayList<Pair<K3, V3>>();
-
-    for (Pair<K2, List<V2>> input : reduceInputs) {
-      K2 inputKey = input.getFirst();
-      List<V2> inputValues = input.getSecond();
-      StringBuilder sb = new StringBuilder();
-      formatValueList(inputValues, sb);
-      LOG.debug("Reducing input (" + inputKey.toString() + ", "
-          + sb.toString() + ")");
-
-      reduceOutputs.addAll(new ReduceDriver<K2, V2, K3, V3>(myReducer)
-              .withCounters(getCounters()).withConfiguration(configuration)
-              .withInputKey(inputKey).withInputValues(inputValues).run());
-    }
-
-    return reduceOutputs;
-  }
-
-  @Override
-  public String toString() {
-    return "MapReduceDriver (0.20+) (" + myMapper + ", " + myReducer + ")";
-  }
-  
-  /** 
-   * @param configuration The configuration object that will given to the 
-   *        mapper and reducer associated with the driver
-   * @return this driver object for fluent coding
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withConfiguration(
-      Configuration configuration) {
-    setConfiguration(configuration);
-    return this;
-  }
-  
-  /**
-   * Identical to {@link #setKeyGroupingComparator(RawComparator)}, but with a 
-   * fluent programming style 
-   * @param groupingComparator Comparator to use in the shuffle stage for key 
-   * grouping 
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withKeyGroupingComparator(
-      RawComparator<K2> groupingComparator) {
-    setKeyGroupingComparator(groupingComparator);
-    return this;
-  }
-  
-  /**
-   * Identical to {@link #setKeyOrderComparator(RawComparator)}, but with a 
-   * fluent programming style 
-   * @param orderComparator Comparator to use in the shuffle stage for key 
-   * value ordering 
-   * @return this
-   */
-  public MapReduceDriver<K1, V1, K2, V2, K3, V3> withKeyOrderComparator(
-      RawComparator<K2> orderComparator) {
-    setKeyOrderComparator(orderComparator);
-    return this;
-  }
-}
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/ReduceDriver.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/ReduceDriver.java
deleted file mode 100644
index eed700c..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/ReduceDriver.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.mapreduce.Counters;
-import org.apache.hadoop.mapreduce.Reducer;
-import org.apache.hadoop.mapreduce.lib.reduce.WrappedReducer;
-import org.apache.hadoop.mrunit.ReduceDriverBase;
-import org.apache.hadoop.mrunit.mapreduce.mock.MockReduceContext;
-import org.apache.hadoop.mrunit.types.Pair;
-
-/**
- * Harness that allows you to test a Reducer instance. You provide a key and a
- * set of intermediate values for that key that represent inputs that should
- * be sent to the Reducer (as if they came from a Mapper), and outputs you
- * expect to be sent by the Reducer to the collector. By calling runTest(),
- * the harness will deliver the input to the Reducer and will check its
- * outputs against the expected results. This is designed to handle a single
- * (k, v*) -> (k, v)* case from the Reducer, representing a single unit test.
- * Multiple input (k, v*) sets should go in separate unit tests.
- */
-public class ReduceDriver<K1, V1, K2, V2> extends ReduceDriverBase<K1, V1, K2, V2> {
-
-  public static final Log LOG = LogFactory.getLog(ReduceDriver.class);
-
-  private Reducer<K1, V1, K2, V2> myReducer;
-  private Counters counters;
-
-  public ReduceDriver(final Reducer<K1, V1, K2, V2> r) {
-    myReducer = r;
-    counters = new Counters();
-  }
-
-  public ReduceDriver() {
-    counters = new Counters();
-  }
-
-  /**
-   * Sets the reducer object to use for this test
-   *
-   * @param r
-   *          The reducer object to use
-   */
-  public void setReducer(Reducer<K1, V1, K2, V2> r) {
-    myReducer = r;
-  }
-
-  /**
-   * Identical to setReducer(), but with fluent programming style
-   *
-   * @param r
-   *          The Reducer to use
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withReducer(Reducer<K1, V1, K2, V2> r) {
-    setReducer(r);
-    return this;
-  }
-
-  public Reducer<K1, V1, K2, V2> getReducer() {
-    return myReducer;
-  }
-
-  /** @return the counters used in this test */
-  public Counters getCounters() {
-    return counters;
-  }
-
-  /** Sets the counters object to use for this test.
-   * @param ctrs The counters object to use.
-   */
-  public void setCounters(final Counters ctrs) {
-    this.counters = ctrs;
-  }
-
-  /** Sets the counters to use and returns self for fluent style */
-  public ReduceDriver<K1, V1, K2, V2> withCounters(final Counters ctrs) {
-    setCounters(ctrs);
-    return this;
-  }
-
-  /**
-   * Identical to setInputKey() but with fluent programming style
-   *
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInputKey(K1 key) {
-    setInputKey(key);
-    return this;
-  }
-
-  /**
-   * Identical to addInputValue() but with fluent programming style
-   *
-   * @param val
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInputValue(V1 val) {
-    addInputValue(val);
-    return this;
-  }
-
-  /**
-   * Identical to addInputValues() but with fluent programming style
-   *
-   * @param values
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInputValues(List<V1> values) {
-    addInputValues(values);
-    return this;
-  }
-
-  /**
-   * Identical to setInput() but returns self for fluent programming style
-   *
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInput(K1 key, List<V1> values) {
-    setInput(key, values);
-    return this;
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   *
-   * @param outputRecord
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withOutput(Pair<K2, V2> outputRecord) {
-    addOutput(outputRecord);
-    return this;
-  }
-
-  /**
-   * Works like addOutput(), but returns self for fluent style
-   *
-   * @param key The key part of a (k, v) pair to add
-   * @param val The val part of a (k, v) pair to add
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withOutput(K2 key, V2 val) {
-    addOutput(key, val);
-    return this;
-  }
-
-  /**
-   * Identical to setInput, but with a fluent programming style
-   *
-   * @param input
-   *          A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withInputFromString(String input) {
-    setInputFromString(input);
-    return this;
-  }
-
-  /**
-   * Identical to addOutput, but with a fluent programming style
-   *
-   * @param output
-   *          A string of the form "key \t val". Trims any whitespace.
-   * @return this
-   */
-  public ReduceDriver<K1, V1, K2, V2> withOutputFromString(String output) {
-    addOutputFromString(output);
-    return this;
-  }
-
-  @Override
-  public List<Pair<K2, V2>> run() throws IOException {
-    List<Pair<K1, List<V1>>> inputs = new ArrayList<Pair<K1, List<V1>>>();
-    inputs.add(new Pair<K1, List<V1>>(inputKey, inputValues));
-
-    try {
-      MockReduceContext<K1, V1, K2, V2> context = 
-        new MockReduceContext<K1, V1, K2, V2>(configuration, inputs, getCounters());
-      myReducer.run(new WrappedReducer<K1, V1, K2, V2>().getReducerContext(context));
-      return context.getOutputs();
-    } catch (InterruptedException ie) {
-      throw new IOException(ie);
-    }
-  }
-
-  @Override
-  public String toString() {
-    return "ReduceDriver (0.20+) (" + myReducer + ")";
-  }
-  
-  /** 
-   * @param configuration The configuration object that will given to the 
-   *        reducer associated with the driver
-   * @return this object for fluent coding
-   */
-  public ReduceDriver<K1, V1, K2, V2> withConfiguration(
-      Configuration configuration) {
-    setConfiguration(configuration);
-    return this;
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockInputSplit.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockInputSplit.java
deleted file mode 100644
index b719ed2..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockInputSplit.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce.mock;
-
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.mapreduce.lib.input.FileSplit;
-
-import java.io.IOException;
-
-/**
- * Mock implementation of InputSplit that does nothing.
- */
-public class MockInputSplit extends FileSplit {
-
-  private static final Path MOCK_PATH = new Path("somefile");
-
-  public MockInputSplit() {
-    super(MOCK_PATH, 0, 0, (String []) null);
-  }
-
-  public String toString() {
-    return "MockInputSplit";
-  }
-
-  /**
-   * Return the path object represented by this as a FileSplit.
-   */
-  public static Path getMockPath() {
-    return MOCK_PATH;
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockMapContext.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockMapContext.java
deleted file mode 100644
index 609c7a5..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockMapContext.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce.mock;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.mapreduce.Counters;
-import org.apache.hadoop.mapreduce.InputSplit;
-import org.apache.hadoop.mapreduce.TaskAttemptID;
-import org.apache.hadoop.mapreduce.TaskType;
-import org.apache.hadoop.mapreduce.task.MapContextImpl;
-import org.apache.hadoop.mrunit.mock.MockOutputCollector;
-import org.apache.hadoop.mrunit.types.Pair;
-
-public class MockMapContext<KEYIN, VALUEIN, KEYOUT, VALUEOUT> 
-    extends MapContextImpl<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
-
-  private Iterator<Pair<KEYIN, VALUEIN>> inputIter;
-  private Pair<KEYIN, VALUEIN> curInput;
-  private MockOutputCollector<KEYOUT, VALUEOUT> output;
-  
-  /**
-   * Create a new instance with the passed configuration, map key/value input 
-   * pairs and counters
-   * 
-   * @param configuration Configuration for the mapper
-   * @param in input key/value pairs for the mapper
-   * @param counters pre-initialized counter values
-   */
-  public MockMapContext(final Configuration configuration,
-                        final List<Pair<KEYIN, VALUEIN>> in, 
-                        final Counters counters) {
-    super(configuration,
-        new TaskAttemptID("mrunit-jt", 0, TaskType.MAP, 0, 0),
-        null, null, new MockOutputCommitter(), new MockReporter(counters), null);
-    this.inputIter = in.iterator();
-    this.output = new MockOutputCollector<KEYOUT, VALUEOUT>();
-  }
-  
-  /**
-   * Create a new instance with the passed map key/value input pairs and
-   * counters. A new {@link Configuration} object will be created and used
-   * to configure the mapper
-   * 
-   * @param in input key/value pairs for the mapper
-   * @param counters pre-initialized counter values
-   */
-  public MockMapContext(final List<Pair<KEYIN, VALUEIN>> in, 
-          final Counters counters) {
-    this(new Configuration(), in, counters);  
-  }
-  
-  @Override
-  public InputSplit getInputSplit() {
-    return new MockInputSplit();
-  }
-
-  @Override
-  public KEYIN getCurrentKey() {
-    return curInput.getFirst();
-  }
-
-  @Override
-  public VALUEIN getCurrentValue() {
-    return curInput.getSecond();
-  }
-
-  @Override
-  public boolean nextKeyValue() throws IOException {
-    if (this.inputIter.hasNext()) {
-      this.curInput = this.inputIter.next();
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  public void write(KEYOUT key, VALUEOUT value) throws IOException {
-    output.collect(key, value);
-  }
-
-  @Override
-  /** This method does nothing in the mock version. */
-  public void progress() {
-  }
-
-  @Override
-  /** This method does nothing in the mock version. */
-  public void setStatus(String status) {
-  }
-
-  /**
-   * @return the outputs from the MockOutputCollector back to
-   * the test harness.
-   */
-  public List<Pair<KEYOUT, VALUEOUT>> getOutputs() {
-    return output.getOutputs();
-  }
-}
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockOutputCommitter.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockOutputCommitter.java
deleted file mode 100644
index 4a546a9..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockOutputCommitter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce.mock;
-
-import org.apache.hadoop.mapreduce.OutputCommitter;
-import org.apache.hadoop.mapreduce.JobContext;
-import org.apache.hadoop.mapreduce.TaskAttemptContext;
-
-import java.io.IOException;
-
-/**
- * Mock implementation of OutputCommitter that does nothing.
- */
-public class MockOutputCommitter extends OutputCommitter {
-
-  public void setupJob(JobContext jobContext) {
-  }
-
-  public void cleanupJob(JobContext jobContext) {
-  }
-
-  public void setupTask(TaskAttemptContext taskContext) {
-  }
-
-  public boolean needsTaskCommit(TaskAttemptContext taskContext) {
-    return false;
-  }
-
-  public void commitTask(TaskAttemptContext taskContext) {
-  }
-
-  public void abortTask(TaskAttemptContext taskContext) {
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockRawKeyValueIterator.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockRawKeyValueIterator.java
deleted file mode 100644
index 3f2d252..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockRawKeyValueIterator.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce.mock;
-
-import org.apache.hadoop.io.DataInputBuffer;
-import org.apache.hadoop.util.Progress;
-import org.apache.hadoop.mapred.RawKeyValueIterator;
-
-import java.io.IOException;
-
-/**
- * Mock implementation of RawKeyValueIterator that does nothing.
- */
-public class MockRawKeyValueIterator implements RawKeyValueIterator {
-  public DataInputBuffer getKey() {
-    return null;
-  }
-
-  public DataInputBuffer getValue() {
-    return null;
-  }
-
-  public boolean next() {
-    return false;
-  }
-
-  public void close() {
-  }
-
-  public Progress getProgress() {
-    return null;
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockReduceContext.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockReduceContext.java
deleted file mode 100644
index 74c1f3b..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockReduceContext.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce.mock;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapreduce.Counters;
-import org.apache.hadoop.mapreduce.TaskAttemptID;
-import org.apache.hadoop.mapreduce.TaskType;
-import org.apache.hadoop.mapreduce.task.ReduceContextImpl;
-import org.apache.hadoop.mrunit.mock.MockOutputCollector;
-import org.apache.hadoop.mrunit.types.Pair;
-
-public class MockReduceContext <KEYIN, VALUEIN, KEYOUT, VALUEOUT>
-    extends ReduceContextImpl<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
-
-  // The iterator over the input key, list(val).
-  private Iterator<Pair<KEYIN, List<VALUEIN>>> inputIter;
-
-  // The current key and list of values.
-  private KEYIN curKey;
-  private InspectableIterable curValueIterable;
-
-  private MockOutputCollector<KEYOUT, VALUEOUT> output;
-
-  /**
-   * Create a new instance with the passed configuration, reducer key/values input 
-   * pairs and counters
-   * 
-   * @param configuration Configuration for the mapper
-   * @param in input key/value pairs for the mapper
-   * @param counters pre-initialized counter values
-   * 
-   * @throws IOException
-   * @throws InterruptedException
-   */
-  public MockReduceContext(Configuration configuration, 
-                           final List<Pair<KEYIN, List<VALUEIN>>> in, 
-                           final Counters counters) 
-  throws IOException, InterruptedException {
-    super(configuration,
-          new TaskAttemptID("mrunit-jt", 0, TaskType.REDUCE, 0, 0),
-          new MockRawKeyValueIterator(), null, null, null,
-          new MockOutputCommitter(), new MockReporter(counters), null,
-          (Class) Text.class, (Class) Text.class);
-    this.inputIter = in.iterator();
-    this.output = new MockOutputCollector<KEYOUT, VALUEOUT>();
-  }
-  
-  /**
-   * Create a new instance with the passed reducer key/values input pairs and
-   * counters. A new {@link Configuration} object will be created and used
-   * to configure the reducer
-   * 
-   * @param in input key/values pairs for the reducer
-   * @param counters pre-initialized counter values
-   */
-  public MockReduceContext(final List<Pair<KEYIN, List<VALUEIN>>> in, 
-          final Counters counters) 
-  throws IOException, InterruptedException {
-    this(new Configuration(), in, counters);
-  }
-
-  /**
-   * A private iterable/iterator implementation that wraps around the 
-   * underlying iterable/iterator used by the input value list. This
-   * memorizes the last value we saw so that we can return it in getCurrentValue().
-   */
-  private class InspectableIterable implements Iterable<VALUEIN> {
-    private Iterable<VALUEIN> base;
-    private VALUEIN lastVal;
-    private boolean used; // if true, don't re-iterate.
-
-    public InspectableIterable(final Iterable<VALUEIN> baseCollection) {
-      this.base = baseCollection;
-    }
-
-    public Iterator<VALUEIN> iterator() {
-      if (used) {
-        return new NullIterator();
-      } else {
-        used = true;
-        return new InspectableIterator(this.base.iterator());
-      }
-    }
-
-    public VALUEIN getLastVal() {
-      return lastVal;
-    }
-
-    private class NullIterator
-        extends ReduceContextImpl<KEYIN, VALUEIN, KEYOUT, VALUEOUT>.ValueIterator
-        implements Iterator<VALUEIN> {
-      public VALUEIN next() {
-        return null;
-      }
-
-      public boolean hasNext() {
-        return false;
-      }
-
-      public void remove() {
-      }
-    }
-
-    private class InspectableIterator
-        extends ReduceContextImpl<KEYIN, VALUEIN, KEYOUT, VALUEOUT>.ValueIterator
-        implements Iterator<VALUEIN> {
-      private Iterator<VALUEIN> iter;
-      public InspectableIterator(final Iterator<VALUEIN> baseIter) {
-        iter = baseIter;
-      }
-
-      public VALUEIN next() {
-        InspectableIterable.this.lastVal = iter.next();
-        return InspectableIterable.this.lastVal;
-      }
-
-      public boolean hasNext() {
-        return iter.hasNext();
-      }
-
-      public void remove() {
-        iter.remove();
-      }
-    }
-  }
-
-  @Override
-  public boolean nextKey() {
-    if (inputIter.hasNext()) {
-      // Advance to the next key and list of values
-      Pair<KEYIN, List<VALUEIN>> p = inputIter.next();
-      curKey = p.getFirst();
-
-      // Reset the value iterator
-      curValueIterable = new InspectableIterable(p.getSecond());
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  @Override
-  public boolean nextKeyValue() {
-    return nextKey();
-  }
-
-  @Override
-  public KEYIN getCurrentKey() {
-    return curKey;
-  }
-
-  @Override
-  public VALUEIN getCurrentValue() {
-    return curValueIterable.getLastVal();
-  }
-
-  @Override
-  public Iterable<VALUEIN> getValues() {
-    return curValueIterable;
-  }
-
-  public void write(KEYOUT key, VALUEOUT value) throws IOException {
-    output.collect(key, value);
-  }
-
-  @Override
-  /** This method does nothing in the mock version. */
-  public void progress() {
-  }
-
-  @Override
-  /** This method does nothing in the mock version. */
-  public void setStatus(String status) {
-  }
-
-  /**
-   * @return the outputs from the MockOutputCollector back to
-   * the test harness.
-   */
-  public List<Pair<KEYOUT, VALUEOUT>> getOutputs() {
-    return output.getOutputs();
-  }
-}
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockReporter.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockReporter.java
deleted file mode 100644
index 621344a..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mapreduce/mock/MockReporter.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce.mock;
-
-import org.apache.hadoop.mapreduce.Counter;
-import org.apache.hadoop.mapreduce.Counters;
-import org.apache.hadoop.mapreduce.StatusReporter;
-
-public class MockReporter extends StatusReporter {
-
-  private Counters counters;
-
-  public MockReporter(final Counters ctrs) {
-    this.counters = ctrs;
-  }
-
-  @Override
-  public void setStatus(String status) {
-    // do nothing.
-  }
-
-  @Override
-  public void progress() {
-    // do nothing.
-  }
-
-  @Override
-  public Counter getCounter(String group, String name) {
-    Counter counter = null;
-    if (counters != null) {
-      counter = counters.findCounter(group, name);
-    }
-
-    return counter;
-  }
-
-  @Override
-  public Counter getCounter(Enum key) {
-    Counter counter = null;
-    if (counters != null) {
-      counter = counters.findCounter(key);
-    }
-
-    return counter;
-  }
-  
-  @Override
-  public float getProgress() {
-    return 0;
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockInputSplit.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockInputSplit.java
deleted file mode 100644
index b476a1b..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockInputSplit.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mock;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.mapred.FileSplit;
-import org.apache.hadoop.mapred.InputSplit;
-
-/**
- * A fake InputSplit object to be returned by our MockReporter to the user
- * class.
- */
-public class MockInputSplit extends FileSplit implements InputSplit {
-
-  private static final Path MOCK_PATH = new Path("somefile");
-
-  public MockInputSplit() {
-    super(MOCK_PATH, 0, 0, (String []) null);
-  }
-
-  @Override
-  public long getLength() {
-    return 0;
-  }
-
-  @Override
-  public String[] getLocations() throws IOException {
-    return null;
-  }
-
-  @Override
-  public void readFields(DataInput in) throws IOException {
-  }
-
-  @Override
-  public void write(DataOutput out) throws IOException {
-  }
-
-  public String toString() {
-    return "MockInputSplit";
-  }
-
-
-  /**
-   * Return the path object represented by this as a FileSplit.
-   */
-  public static Path getMockPath() {
-    return MOCK_PATH;
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockOutputCollector.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockOutputCollector.java
deleted file mode 100644
index 34368fb..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockOutputCollector.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mock;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.io.DataInputBuffer;
-import org.apache.hadoop.io.DataOutputBuffer;
-import org.apache.hadoop.io.serializer.Deserializer;
-import org.apache.hadoop.io.serializer.SerializationFactory;
-import org.apache.hadoop.io.serializer.Serializer;
-import org.apache.hadoop.mapred.OutputCollector;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.apache.hadoop.util.ReflectionUtils;
-
-
-/**
- * OutputCollector to use in the test framework for Mapper and Reducer
- * classes. Accepts a set of output (k, v) pairs and returns them to the
- * framework for validation.
- */
-public class MockOutputCollector<K, V> implements OutputCollector<K, V> {
-
-  private ArrayList<Pair<K, V>> collectedOutputs;
-  private SerializationFactory serializationFactory;
-  private DataOutputBuffer outBuffer;
-  private DataInputBuffer inBuffer;
-  private Configuration conf;
-
-
-  public MockOutputCollector() {
-    collectedOutputs = new ArrayList<Pair<K, V>>();
-
-    outBuffer = new DataOutputBuffer();
-    inBuffer = new DataInputBuffer();
-
-    conf = new Configuration();
-    serializationFactory = new SerializationFactory(conf);
-  }
-
-
-  private Object getInstance(Class klazz) {
-    return ReflectionUtils.newInstance(klazz, conf);
-  }
-
-
-  private Object deepCopy(Object obj) throws IOException {
-
-    if (null == obj) {
-      return null;
-    }
-
-    Class klazz = obj.getClass();
-    Object out = getInstance(klazz); // the output object to return.
-    Serializer s = serializationFactory.getSerializer(klazz);
-    Deserializer ds = serializationFactory.getDeserializer(klazz);
-
-    try {
-      s.open(outBuffer);
-      ds.open(inBuffer);
-
-      outBuffer.reset();
-      s.serialize(obj);
-
-      byte [] data = outBuffer.getData();
-      int len = outBuffer.getLength();
-      inBuffer.reset(data, len);
-
-      out = ds.deserialize(out);
-
-      return out;
-    } finally {
-      try {
-        s.close();
-      } catch (IOException ioe) {
-        // ignore this; we're closing.
-      }
-
-      try {
-        ds.close();
-      } catch (IOException ioe) {
-        // ignore this; we're closing.
-      }
-    }
-  }
-
-  /**
-   * Accepts another (key, value) pair as an output of this mapper/reducer.
-   */
-  public void collect(K key, V value) throws IOException {
-    collectedOutputs.add(new Pair<K, V>((K) deepCopy(key), (V) deepCopy(value)));
-  }
-
-  /**
-   * @return The outputs generated by the mapper/reducer being tested
-   */
-  public List<Pair<K, V>> getOutputs() {
-    return collectedOutputs;
-  }
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockReporter.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockReporter.java
deleted file mode 100644
index 03bbf6c..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/mock/MockReporter.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mock;
-
-import org.apache.hadoop.mapred.Counters;
-import org.apache.hadoop.mapred.InputSplit;
-import org.apache.hadoop.mapred.Reporter;
-import org.apache.hadoop.mapred.Counters.Counter;
-
-public class MockReporter implements Reporter {
-
-  private MockInputSplit inputSplit = new MockInputSplit();
-  private Counters counters;
-
-  public enum ReporterType {
-    Mapper,
-    Reducer
-  }
-
-  private ReporterType typ;
-
-  public MockReporter(final ReporterType kind, final Counters ctrs) {
-    this.typ = kind;
-    this.counters = ctrs;
-  }
-
-  @Override
-  public InputSplit getInputSplit() {
-    if (typ == ReporterType.Reducer) {
-      throw new UnsupportedOperationException(
-              "Reducer cannot call getInputSplit()");
-    } else {
-      return inputSplit;
-    }
-  }
-
-  @Override
-  public void incrCounter(Enum key, long amount) {
-    if (null != counters) {
-      counters.incrCounter(key, amount);
-    }
-  }
-
-  @Override
-  public void incrCounter(String group, String counter, long amount) {
-    if (null != counters) {
-      counters.incrCounter(group, counter, amount);
-    }
-  }
-
-  @Override
-  public void setStatus(String status) {
-    // do nothing.
-  }
-
-  @Override
-  public void progress() {
-    // do nothing.
-  }
-
-  @Override
-  public Counter getCounter(String group, String name) {
-    Counters.Counter counter = null;
-    if (counters != null) {
-      counter = counters.findCounter(group, name);
-    }
-
-    return counter;
-  }
-
-  @Override
-  public Counter getCounter(Enum key) {
-    Counters.Counter counter = null;
-    if (counters != null) {
-      counter = counters.findCounter(key);
-    }
-
-    return counter;
-  }
-  
-  public float getProgress() {
-    return 0;
-  };
-}
-
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/package.html b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/package.html
deleted file mode 100644
index 6b111f6..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/package.html
+++ /dev/null
@@ -1,221 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF 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.
--->
-
-<body>
-<div id="header">
-<h1>MRUnit</h1>
-</div>
-<div id="content">
-<div id="preamble">
-<div class="sectionbody">
-<div class="paragraph"><p>MRUnit is a unit test library designed to facilitate easy integration between
-your MapReduce development process and standard development and testing tools
-such as JUnit. MRUnit contains mock objects that behave like classes you
-interact with during MapReduce execution (e.g., <tt>InputSplit</tt> and
-<tt>OutputCollector</tt>) as well as test harness "drivers" that test your program&#8217;s
-correctness while maintaining compliance with the MapReduce semantics. <em>Mapper</em>
-and <em>Reducer</em> implementations can be tested individually, as well as together to
-form a full MapReduce job.</p></div>
-<div class="paragraph"><p>This document describes how to get started using MRUnit to unit test your Mapper
-and Reducer implementations.</p></div>
-</div>
-</div>
-<h2 id="_getting_started_with_mrunit">Getting Started with MRUnit</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>MRUnit is compiled as a jar and resides in <tt>$HADOOP_PREFIX/contrib/mrunit</tt>.
-MRUnit is designed to augment an existing unit test framework such as JUnit.</p></div>
-<div class="paragraph"><p>To use MRUnit, add the MRUnit JAR from the above path to the classpath or
-project build path in your development environment (ant buildfile, Eclipse
-project, etc.).</p></div>
-</div>
-<h2 id="_an_example">An Example</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>The following example test case demonstrates how to use MRUnit:</p></div>
-<div class="listingblock">
-<div class="content">
-<pre><tt>import junit.framework.TestCase;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.lib.IdentityMapper;
-import org.apache.hadoop.mrunit.MapDriver;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestExample extends TestCase {
-
-  private Mapper mapper;
-  private MapDriver driver;
-
-  @Before
-  public void setUp() {
-    mapper = new IdentityMapper();
-    driver = new MapDriver(mapper);
-  }
-
-  @Test
-  public void testIdentityMapper() {
-    driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-  }
-}</tt></pre>
-</div></div>
-<div class="paragraph"><p>In this example, we see an existing <tt>Mapper</tt> implementation (<tt>IdentityMapper</tt>)
-being tested. We made a class named <tt>TestExample</tt> designed to test this mapper
-implementation. In JUnit, each particular test is created in a separate method
-whose name begins with test, and is marked with the <tt>@Test</tt> annotation. All of
-the <tt>test*()</tt> methods are run in succession. Before each test method, the
-<tt>setUp()</tt> method (if one is present) is executed. After each test, a
-<tt>tearDown()</tt> method, if one exists, is executed. (In this example, no
-<tt>tearDown()</tt> takes place.)</p></div>
-<div class="paragraph"><p>MRUnit is designed to allow you to test the precise actions of a particular
-class. Here we&#8217;re verifying that the <tt>IdentityMapper</tt> emits the same (key,
-value) pair that is provided to it as input. This test process is facilitated
-by a driver. In the <tt>setUp()</tt> method, we created an instance of the
-<tt>IdentityMapper</tt> that we want to test, as well as a <tt>MapDriver</tt> to run the
-test. In the <tt>testIdentityMapper()</tt> method, we configure the driver to pass the
-(key, value) pair <tt>("foo", "bar")</tt> to our mapper as input. When <tt>runTest()</tt> is
-called, the <tt>MapDriver</tt> will send this single (key, value) pair as input to a
-mapper. We also configured the driver to expect the (key, value) pair <tt>("foo",
-"bar")</tt> as output.  After the planned input and expected output are configured,
-<tt>runTest()</tt> invokes the mapper on the input, and compares the expected and
-actual outputs. If these mismatch, it causes the JUnit test to fail.</p></div>
-</div>
-<h2 id="_test_drivers_and_running_tests">Test Drivers and Running Tests</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>Each MRUnit test is designed to test a mapper, a reducer, or a mapper/reducer
-pair (i.e., a "job"). MRUnit provides three <em>TestDriver</em> classes that are
-designed to test each of these three scenarios. A <strong><tt>MapDriver</tt></strong> will provide a
-single (key, value) pair as input to an instance of the <em>Mapper</em> interface.
-When its <tt>run()</tt> or <tt>runTest()</tt> method is called, the mapper&#8217;s <tt>map()</tt> method
-is called with the provided (key, value) pair, as well as MRUnit-specific
-implementations of <tt>OutputCollector</tt> and <tt>Reporter</tt>. After the mapper
-completes, any output (key, value) pairs sent to this <tt>OutputCollector</tt> are
-compiled into a list.</p></div>
-<div class="paragraph"><p>If the test was launched via <tt>MapDriver.runTest()</tt>, the emitted (key, value)
-pairs are compared with the (key, value) pairs provided to the <tt>MapDriver</tt> as
-expected output. The driver uses <tt>equals()</tt> to determine whether the emitted
-value list is equal to the expected value list. If these differ, the driver
-raises a JUnit assertion failure to signify a failing test.</p></div>
-<div class="paragraph"><p>If the test was launched via <tt>MapDriver.run()</tt>, the emitted (key, value) pair
-list is returned to the calling method, where you can process the outputs using
-your own logic to assess the success or failure of the test.</p></div>
-<div class="paragraph"><p>Similar to the <tt>MapDriver</tt> implementation, <strong><tt>ReduceDriver</tt></strong> will put a single
-<em>Reducer</em> implementation under test. A single input key is provided, as well as
-an ordered list of input values. The reducer receives an iterator over this
-list of values, as well as the input key. It may emit an arbitrary number of
-output (key, value) pairs; <tt>runTest()</tt> will compare these against a list
-provided as expected output.</p></div>
-<div class="paragraph"><p>Finally, one may want to test a complete MapReduce job consisting of a mapper
-and a reducer composed together. The <strong><tt>MapReduceDriver</tt></strong> receives a <em>Mapper</em>
-and <em>Reducer</em> implementation, as well as an arbitrary number of (key, value)
-pairs as input. These are used as inputs to the <tt>Mapper.map()</tt> method. The
-outputs from these map calls are put through a process similar to shuffling
-when <tt>mapred.reduce.tasks</tt> is set to 1. No partitioner is called, but the
-values are aggregated by key and the keys are sorted by their <tt>compareTo()</tt>
-methods. The <tt>Reducer.reduce()</tt> method is called to process these intermediate
-(key, value list) sets in order. Finally, the output (key, value) pairs are
-again compared with any expected values provided by the user.</p></div>
-</div>
-<h2 id="_configuring_tests">Configuring Tests</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>MRUnit provides multiple ways of configuring individual tests to facilitate
-different programming styles.</p></div>
-<h3 id="_setter_methods">Setter Methods</h3><div style="clear:left"></div>
-<div class="paragraph"><p>Various setter methods allow you to set the mapper/reducer classes under test,
-or the input (key, value) pair. e.g., <tt>myMapDriver.setInputPair(key, value)</tt>.
-Because a mapper may emit multiple (key, value) pairs as output, outputs are
-set with <tt>myMapDriver.addOutputPair(key, value)</tt>. These expected outputs are
-added to an ordered list.</p></div>
-<h3 id="_fluent_programming_style">Fluent Programming Style</h3><div style="clear:left"></div>
-<div class="paragraph"><p>Another alternate mechanism for configuring tests (which is also the author&#8217;s
-preferred way) is to use "fluent" methods. Several methods whose names begin
-with with will set a configuration input, and return this. These calls can be
-chained together (as done in the example above) to concisely specify all the
-inputs to the test process; e.g., <tt>myMapDriver.withInputPair(k1,
-v1).withOutputPair(k2, v2).runTest()</tt>.</p></div>
-</div>
-<h2 id="_additional_api_features">Additional API Features</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>This section describes additional features of the MRUnit API.</p></div>
-<h3 id="_mock_objects">Mock Objects</h3><div style="clear:left"></div>
-<div class="paragraph"><p>To facilitate calls to <tt>map()</tt> and <tt>reduce()</tt>, MRUnit provides mock
-implementations of the classes used for non-user provided arguments. The
-<tt>MockReporter</tt> implementation ignores most of its function calls except
-<tt>getInputSplit()</tt>, which returns a <tt>MockInputSplit</tt>, and the counter-increment
-methods. <tt>MockInputSplit</tt> subclasses <tt>FileInputSplit</tt> and contains a dummy
-filename, but otherwise does nothing. The <tt>MockOutputCollector</tt> aggregates
-(key, value) pairs sent to it via <tt>collect()</tt> into a list. This list is then
-used during the shuffling or output comparson functions. Unlike the full Hadoop
-job running process, this list is not spilled to disk nor are any memory
-management methods used. It is assumed that the volume of data used during
-MRUnit does not exceed the available heap size.</p></div>
-<h3 id="_additional_test_drivers">Additional Test Drivers</h3><div style="clear:left"></div>
-<div class="paragraph"><p>MRUnit comes with an additional test driver called the <strong><tt>PipelineMapReduceDriver</tt></strong>
-which allows testing of a series of MapReduce passes. By calling the <tt>addMapReduce()</tt>
-or <tt>withMapReduce()</tt> methods, an additional mapper and reducer pass can be added
-to the pipeline under test.</p></div>
-<div class="paragraph"><p>By calling <tt>runTest()</tt>, the harness will deliver the input to the first
-<em>Mapper</em>, feed the intermediate results to the first <em>Reducer</em> (without checking
-them), and proceed to forward this data along to subsequent <em>Mapper</em>/<em>Reducer</em>
-jobs in the pipeline until the final <em>Reducer</em>. The last <em>Reducer</em>'s outputs are
-checked against the expected results.</p></div>
-<div class="paragraph"><p>This is designed for slightly more complicated integration tests than the
-<tt>MapReduceDriver</tt>, which is for smaller unit tests.</p></div>
-<div class="paragraph"><p><tt>(K1, V1)</tt> in the type signature refer to the types associated with the inputs
-to the first <em>Mapper</em>. <tt>(K2, V2)</tt> refer to the types associated with the final
-<em>Reducer</em>'s output. No intermediate types are specified.</p></div>
-<h3 id="_testing_combiners">Testing Combiners</h3><div style="clear:left"></div>
-<div class="paragraph"><p>The <tt>MapReduceDriver</tt> will allow you to test a combiner in addition to a mapper
-and reducer. The <tt>setCombiner()</tt> method configures the driver to pass all mapper
-output (key, value) pairs through a combiner before being sent to the reducer
-under test.</p></div>
-<h3 id="_counters">Counters</h3><div style="clear:left"></div>
-<div class="paragraph"><p>The test drivers support testing of the <tt>Counters</tt> system in Hadoop. The
-<tt>Reporter.incrCounter()</tt> method works as it usually does inside <em>Mapper</em>
-or <em>Reducer</em> instances under test. The TestDriver implementation itself holds
-a <tt>Counters</tt> object which can be retrieved with <tt>getCounters()</tt>. You can then
-verify the correct counter values have been set by your code under test.</p></div>
-<div class="paragraph"><p>The <tt>setCounters()</tt> and <tt>withCounters()</tt> methods allow you to set the
-<tt>Counters</tt> instance being used to accumulate values during testing.</p></div>
-<div class="paragraph"><p>One departure from the typical interface is that in the
-<tt>PipelineMapReduceDriver</tt>, all MapReduce passes share the same <tt>Counters</tt>
-instance and counter values are not reset. If several MapReduce passes are
-tested together, their counter values are accumulated together as well.</p></div>
-</div>
-<h2 id="_the_new_mapreduce_api">The New MapReduce API</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>MRUnit includes support for the "new" (i.e., version 0.20 and later) API
-as well. MRUnit provides <tt>MapDriver</tt>, <tt>ReduceDriver</tt>, and <tt>MapReduceDriver</tt>
-implementations compatable with the new MapReduce (<tt>Context</tt>-based) API
-in the <tt>org.apache.hadoop.mrunit.mapreduce</tt> package. These classes work
-identically to their old-API counterparts in the <tt>org.apache.hadoop.mrunit</tt>
-package, but work with <tt>org.apache.hadoop.mapreduce.Mapper</tt> and
-<tt>org.apache.hadoop.mapreduce.Reducer</tt> instances.</p></div>
-<div class="paragraph"><p>Mock implementations of <tt>InputSplit</tt>, <tt>MapContext</tt>, <tt>OutputCommitter</tt>,
-<tt>ReduceContext</tt>, and <tt>Reporter</tt> compatible with the new interfaces are
-provided.</p></div>
-</div>
-</div>
-<div id="footnotes"><hr /></div>
-</body>
-</html>
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/testutil/ExtendedAssert.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/testutil/ExtendedAssert.java
deleted file mode 100644
index 36a134f..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/testutil/ExtendedAssert.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.testutil;
-
-import java.util.List;
-
-import static org.junit.Assert.*;
-
-public final class ExtendedAssert {
-
-  private ExtendedAssert() { }
-
-  /**
-   * Asserts that all the elements of the list are equivalent under equals()
-   * @param expected a list full of expected values
-   * @param actual a list full of actual test values
-   */
-  public static void assertListEquals(List expected, List actual) {
-    if (expected.size() != actual.size()) {
-      fail("Expected list of size " + expected.size() + "; actual size is "
-          + actual.size());
-    }
-
-    for (int i = 0; i < expected.size(); i++) {
-      Object t1 = expected.get(i);
-      Object t2 = actual.get(i);
-
-      if (!t1.equals(t2)) {
-        fail("Expected element " + t1 + " at index " + i
-            + " != actual element " + t2);
-      }
-    }
-  }
-
-  /**
-   * asserts x &gt; y
-   */
-  public static void assertGreater(int x, int y) {
-    assertTrue("Expected " + x + " > " + y, x > y);
-  }
-
-  /** asserts x &gt;= y) */
-  public static void assertGreaterOrEqual(int x, int y) {
-    assertTrue("Expected " + x + " >= " + y, x >= y);
-  }
-
-  /**
-   * asserts x &lt; y
-   */
-  public static void assertLess(int x, int y) {
-    assertTrue("Expected " + x + " < " + y, x < y);
-  }
-
-  /** asserts x &gt;= y) */
-  public static void assertLessOrEqual(int x, int y) {
-    assertTrue("Expected " + x + " <= " + y, x <= y);
-  }
-}
diff --git a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/types/Pair.java b/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/types/Pair.java
deleted file mode 100644
index fcf1f83..0000000
--- a/src/contrib/mrunit/src/java/org/apache/hadoop/mrunit/types/Pair.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.types;
-
-import java.util.Comparator;
-
-
-/**
- * A very basic pair type.
- */
-public class Pair<S, T> implements Comparable<Pair<S, T>> {
-
-  private final S first;
-  private final T second;
-
-  public Pair(final S car, final T cdr) {
-    first = car;
-    second = cdr;
-  }
-
-  public S getFirst() { return first; }
-  public T getSecond() { return second; }
-
-  @Override
-  public boolean equals(Object o) {
-    if (null == o) {
-      return false;
-    } else if (o instanceof Pair) {
-      Pair<S, T> p = (Pair<S, T>) o;
-      if (first == null && second == null) {
-        return p.first == null && p.second == null;
-      } else if (first == null) {
-        return p.first == null && second.equals(p.second);
-      } else if (second == null) {
-        return p.second == null && first.equals(p.first);
-      } else {
-        return first.equals(p.first) && second.equals(p.second);
-      }
-    } else {
-      return false;
-    }
-  }
-
-  @Override
-  public int hashCode() {
-    int code = 0;
-
-    if (null != first) {
-      code += first.hashCode();
-    }
-
-    if (null != second) {
-      code += second.hashCode() << 1;
-    }
-
-    return code;
-  }
-
-  @Override
-  public int compareTo(Pair<S, T> p) {
-    if (null == p) {
-      return 1;
-    }
-
-    Comparable<S> firstCompare = (Comparable<S>) first;
-
-    int firstResult = firstCompare.compareTo(p.first);
-    if (firstResult == 0) {
-      Comparable<T> secondCompare = (Comparable<T>) second;
-      return secondCompare.compareTo(p.second);
-    } else {
-      return firstResult;
-    }
-  }
-
-  // TODO: Can this be made static? Same with SecondElemComparator?
-  public class FirstElemComparator implements Comparator<Pair<S, T>> {
-    public FirstElemComparator() {
-    }
-
-    public int compare(Pair<S, T> p1, Pair<S, T> p2) {
-      Comparable<S> cS = (Comparable<S>) p1.first;
-      return cS.compareTo(p2.first);
-    }
-  }
-
-  public class SecondElemComparator implements Comparator<Pair<S, T>> {
-    public SecondElemComparator() {
-    }
-
-    public int compare(Pair<S, T> p1, Pair<S, T> p2) {
-      Comparable<T> cT = (Comparable<T>) p1.second;
-      return cT.compareTo(p2.second);
-    }
-  }
-
-  @Override
-  public String toString() {
-    String firstString = "null";
-    String secondString = "null";
-
-    if (null != first) {
-      firstString = first.toString();
-    }
-
-    if (null != second) {
-      secondString = second.toString();
-    }
-
-    return "(" + firstString + ", " + secondString + ")";
-  }
-}
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/AllTests.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/AllTests.java
deleted file mode 100644
index f28fc65..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/AllTests.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-import org.apache.hadoop.mrunit.mock.TestMockReporter;
-import org.apache.hadoop.mrunit.mock.TestMockOutputCollector;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * All tests for MRUnit testing device (org.apache.hadoop.mrunit)
- *
- */
-public final class AllTests  {
-
-  private AllTests() { }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Test for org.apache.hadoop.mrunit");
-
-    suite.addTestSuite(TestMapDriver.class);
-    suite.addTestSuite(TestMapReduceDriver.class);
-    suite.addTestSuite(TestPipelineMapReduceDriver.class);
-    suite.addTestSuite(TestMockReporter.class);
-    suite.addTestSuite(TestMockOutputCollector.class);
-    suite.addTestSuite(TestReduceDriver.class);
-    suite.addTestSuite(TestTestDriver.class);
-    suite.addTestSuite(TestExample.class);
-    suite.addTestSuite(TestCounters.class);
-
-    suite.addTest(org.apache.hadoop.mrunit.types.AllTests.suite());
-    suite.addTest(org.apache.hadoop.mrunit.mapreduce.AllTests.suite());
-    return suite;
-  }
-
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestCounters.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestCounters.java
deleted file mode 100644
index 61f8d02..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestCounters.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-import java.util.Iterator;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Counters;
-import org.apache.hadoop.mapred.MapReduceBase;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.OutputCollector;
-import org.apache.hadoop.mapred.Reducer;
-import org.apache.hadoop.mapred.Reporter;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test counters usage in various drivers.
- */
-public class TestCounters extends TestCase {
-
-  private static final String GROUP = "GROUP";
-  private static final String ELEM = "ELEM";
-
-  private class CounterMapper extends MapReduceBase implements Mapper<Text, Text, Text, Text> {
-    public void map(Text k, Text v, OutputCollector<Text, Text> out, Reporter r)
-        throws IOException {
-
-      r.incrCounter(GROUP, ELEM, 1);
-
-      // Emit the same (k, v) pair twice.
-      out.collect(k, v);
-      out.collect(k, v);
-    }
-  }
-
-  private class CounterReducer extends MapReduceBase implements Reducer<Text, Text, Text, Text> {
-    public void reduce(Text k, Iterator<Text> vals, OutputCollector<Text, Text> out, Reporter r)
-        throws IOException {
-
-      while (vals.hasNext()) {
-        r.incrCounter(GROUP, ELEM, 1);
-        out.collect(k, vals.next());
-      }
-    }
-  }
-
-  @Test
-  public void testMapper() throws IOException {
-    Mapper<Text, Text, Text, Text> mapper = new CounterMapper();
-    MapDriver<Text, Text, Text, Text> driver = new MapDriver<Text, Text, Text, Text>(mapper);
-    driver.withInput(new Text("foo"), new Text("bar")).run();
-    assertEquals("Expected 1 counter increment", 1,
-        driver.getCounters().findCounter(GROUP, ELEM).getValue());
-  }
-
-  @Test
-  public void testReducer() throws IOException {
-    Reducer<Text, Text, Text, Text> reducer = new CounterReducer();
-    ReduceDriver<Text, Text, Text, Text> driver = new ReduceDriver<Text, Text, Text, Text>(reducer);
-    driver.withInputKey(new Text("foo"))
-          .withInputValue(new Text("bar"))
-          .run();
-    assertEquals("Expected 1 counter increment", 1,
-        driver.getCounters().findCounter(GROUP, ELEM).getValue());
-  }
-
-  @Test
-  public void testMapReduce() throws IOException {
-    Mapper<Text, Text, Text, Text> mapper = new CounterMapper();
-    Reducer<Text, Text, Text, Text> reducer = new CounterReducer();
-    MapReduceDriver<Text, Text, Text, Text, Text, Text> driver =
-        new MapReduceDriver<Text, Text, Text, Text, Text, Text>(mapper, reducer);
-
-    driver.withInput(new Text("foo"), new Text("bar"))
-          .run();
-
-    assertEquals("Expected counter=3", 3,
-        driver.getCounters().findCounter(GROUP, ELEM).getValue());
-  }
-
-  @Test
-  public void testPipeline() throws IOException {
-    Mapper<Text, Text, Text, Text> mapper = new CounterMapper();
-    Reducer<Text, Text, Text, Text> reducer = new CounterReducer();
-    PipelineMapReduceDriver<Text, Text, Text, Text> driver =
-        new PipelineMapReduceDriver<Text, Text, Text, Text>();
-
-    driver.withMapReduce(mapper, reducer)
-          .withMapReduce(mapper, reducer)
-          .withInput(new Text("foo"), new Text("bar"))
-          .run();
-
-    assertEquals("Expected counter=9", 9,
-        driver.getCounters().findCounter(GROUP, ELEM).getValue());
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestExample.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestExample.java
deleted file mode 100644
index b11490c..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestExample.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.lib.IdentityMapper;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Example test of the IdentityMapper to demonstrate proper MapDriver
- * usage in a test case.
- *
- * This example is reproduced in the overview for the MRUnit javadoc.
- */
-public class TestExample extends TestCase {
-
-  private Mapper<Text, Text, Text, Text> mapper;
-  private MapDriver<Text, Text, Text, Text> driver;
-
-  @Before
-  public void setUp() {
-    mapper = new IdentityMapper<Text, Text>();
-    driver = new MapDriver<Text, Text, Text, Text>(mapper);
-  }
-
-  @Test
-  public void testIdentityMapper() {
-    driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestMapDriver.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestMapDriver.java
deleted file mode 100644
index 2c4a796..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestMapDriver.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-import static org.apache.hadoop.mrunit.testutil.ExtendedAssert.*;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.lib.IdentityMapper;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestMapDriver extends TestCase {
-
-  private Mapper<Text, Text, Text, Text> mapper;
-  private MapDriver<Text, Text, Text, Text> driver;
-
-  @Before
-  public void setUp() {
-    mapper = new IdentityMapper<Text, Text>();
-    driver = new MapDriver<Text, Text, Text, Text>(mapper);
-  }
-
-  @Test
-  public void testRun() {
-    List<Pair<Text, Text>> out = null;
-
-    try {
-      out = driver.withInput(new Text("foo"), new Text("bar")).run();
-    } catch (IOException ioe) {
-      fail();
-    }
-
-    List<Pair<Text, Text>> expected = new ArrayList<Pair<Text, Text>>();
-    expected.add(new Pair<Text, Text>(new Text("foo"), new Text("bar")));
-
-    assertListEquals(out, expected);
-  }
-
-  @Test
-  public void testTestRun1() {
-    driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun2() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun3() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun4() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("bonusfoo"), new Text("bar"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-
-  }
-  @Test
-  public void testTestRun5() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("somethingelse"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun6() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-              .withOutput(new Text("someotherkey"), new Text("bar"))
-              .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun7() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("someotherkey"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testSetInput() {
-    try {
-      driver.setInput(new Pair<Text, Text>(new Text("foo"), new Text("bar")));
-    } catch (Exception e) {
-      fail();
-    }
-
-    assertEquals(driver.getInputKey(), new Text("foo"));
-    assertEquals(driver.getInputValue(), new Text("bar"));
-  }
-
-  @Test
-  public void testSetInputNull() {
-    try {
-      driver.setInput((Pair<Text, Text>) null);
-      fail();
-    } catch (Exception e) {
-      // expect this.
-    }
-  }
-
-  @Test
-  public void testEmptyInput() {
-    // MapDriver will forcibly map (null, null) as undefined input;
-    // identity mapper expects (null, null) back.
-    driver.withOutput(null, null).runTest();
-  }
-
-  @Test
-  public void testEmptyInput2() {
-    // it is an error to expect no output because we expect
-    // the mapper to be fed (null, null) as an input if the
-    // user doesn't set any input.
-    try {
-      driver.runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestMapReduceDriver.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestMapReduceDriver.java
deleted file mode 100644
index febffa2..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestMapReduceDriver.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-import static org.apache.hadoop.mrunit.testutil.ExtendedAssert.assertListEquals;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.io.RawComparator;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.JobConf;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.OutputCollector;
-import org.apache.hadoop.mapred.Reducer;
-import org.apache.hadoop.mapred.Reporter;
-import org.apache.hadoop.mapred.lib.IdentityMapper;
-import org.apache.hadoop.mapred.lib.IdentityReducer;
-import org.apache.hadoop.mapred.lib.LongSumReducer;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestMapReduceDriver extends TestCase {
-
-  private static final int FOO_IN_A = 42;
-  private static final int FOO_IN_B = 10;
-  private static final int BAR_IN = 12;
-  private static final int FOO_OUT = 52;
-
-  private Mapper<Text, LongWritable, Text, LongWritable> mapper;
-  private Reducer<Text, LongWritable, Text, LongWritable> reducer;
-  private MapReduceDriver<Text, LongWritable,
-                  Text, LongWritable,
-                  Text, LongWritable> driver;
-
-  private MapReduceDriver<Text, Text, Text, Text, Text, Text> driver2;
-
-  @Before
-  public void setUp() throws Exception {
-    mapper = new IdentityMapper<Text, LongWritable>();
-    reducer = new LongSumReducer<Text>();
-    driver = new MapReduceDriver<Text, LongWritable,
-                                 Text, LongWritable,
-                                 Text, LongWritable>(
-                        mapper, reducer);
-    // for shuffle tests
-    driver2 = new MapReduceDriver<Text, Text, Text, Text, Text, Text>();
-  }
-
-  @Test
-  public void testRun() {
-    List<Pair<Text, LongWritable>> out = null;
-    try {
-      out = driver
-              .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-              .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-              .withInput(new Text("bar"), new LongWritable(BAR_IN))
-              .run();
-    } catch (IOException ioe) {
-      fail();
-    }
-
-    List<Pair<Text, LongWritable>> expected =
-      new ArrayList<Pair<Text, LongWritable>>();
-    expected.add(new Pair<Text, LongWritable>(new Text("bar"),
-            new LongWritable(BAR_IN)));
-    expected.add(new Pair<Text, LongWritable>(new Text("foo"),
-            new LongWritable(FOO_OUT)));
-
-    assertListEquals(out, expected);
-  }
-
-  @Test
-  public void testTestRun1() {
-    driver
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun2() {
-    driver
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun3() {
-    try {
-      driver
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected
-    }
-  }
-
-  @Test
-  public void testEmptyInput() {
-    driver.runTest();
-  }
-
-  @Test
-  public void testEmptyInputWithOutputFails() {
-    try {
-      driver
-              .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-              .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testEmptyShuffle() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-    assertEquals(0, outputs.size());
-  }
-
-  // just shuffle a single (k, v) pair
-  @Test
-  public void testSingleShuffle() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("b")));
-
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-
-    List<Pair<Text, List<Text>>> expected = new ArrayList<Pair<Text, List<Text>>>();
-    List<Text> sublist = new ArrayList<Text>();
-    sublist.add(new Text("b"));
-    expected.add(new Pair<Text, List<Text>>(new Text("a"), sublist));
-
-    assertListEquals(expected, outputs);
-  }
-
-  // shuffle multiple values from the same key.
-  @Test
-  public void testShuffleOneKey() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("b")));
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("c")));
-
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-
-    List<Pair<Text, List<Text>>> expected = new ArrayList<Pair<Text, List<Text>>>();
-    List<Text> sublist = new ArrayList<Text>();
-    sublist.add(new Text("b"));
-    sublist.add(new Text("c"));
-    expected.add(new Pair<Text, List<Text>>(new Text("a"), sublist));
-
-    assertListEquals(expected, outputs);
-  }
-
-  // shuffle multiple keys
-  @Test
-  public void testMultiShuffle1() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("x")));
-    inputs.add(new Pair<Text, Text>(new Text("b"), new Text("z")));
-    inputs.add(new Pair<Text, Text>(new Text("b"), new Text("w")));
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("y")));
-
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-
-    List<Pair<Text, List<Text>>> expected = new ArrayList<Pair<Text, List<Text>>>();
-    List<Text> sublist1 = new ArrayList<Text>();
-    sublist1.add(new Text("x"));
-    sublist1.add(new Text("y"));
-    expected.add(new Pair<Text, List<Text>>(new Text("a"), sublist1));
-
-    List<Text> sublist2 = new ArrayList<Text>();
-    sublist2.add(new Text("z"));
-    sublist2.add(new Text("w"));
-    expected.add(new Pair<Text, List<Text>>(new Text("b"), sublist2));
-
-    assertListEquals(expected, outputs);
-  }
-
-
-  // shuffle multiple keys that are out-of-order to start.
-  @Test
-  public void testMultiShuffle2() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    inputs.add(new Pair<Text, Text>(new Text("b"), new Text("z")));
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("x")));
-    inputs.add(new Pair<Text, Text>(new Text("b"), new Text("w")));
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("y")));
-
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-
-    List<Pair<Text, List<Text>>> expected = new ArrayList<Pair<Text, List<Text>>>();
-    List<Text> sublist1 = new ArrayList<Text>();
-    sublist1.add(new Text("x"));
-    sublist1.add(new Text("y"));
-    expected.add(new Pair<Text, List<Text>>(new Text("a"), sublist1));
-
-    List<Text> sublist2 = new ArrayList<Text>();
-    sublist2.add(new Text("z"));
-    sublist2.add(new Text("w"));
-    expected.add(new Pair<Text, List<Text>>(new Text("b"), sublist2));
-
-    assertListEquals(expected, outputs);
-  }
-
-  // Test "combining" with an IdentityReducer. Result should be the same.
-  @Test
-  public void testIdentityCombiner() {
-    driver
-            .withCombiner(new IdentityReducer<Text, LongWritable>())
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .runTest();
-  }
-
-  // Test "combining" with another LongSumReducer. Result should be the same.
-  @Test
-  public void testLongSumCombiner() {
-    driver
-            .withCombiner(new LongSumReducer<Text>())
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .runTest();
-  }
-
-  // Test "combining" with another LongSumReducer, and with the Reducer
-  // set to IdentityReducer. Result should be the same.
-  @Test
-  public void testLongSumCombinerAndIdentityReduce() {
-    driver
-            .withCombiner(new LongSumReducer<Text>())
-            .withReducer(new IdentityReducer<Text, LongWritable>())
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .runTest();
-  }
-  
-  // Test the key grouping and value ordering comparators
-  @Test
-  public void testComparators() {
-    // group comparator - group by first character
-    RawComparator groupComparator = new RawComparator() {
-      @Override
-      public int compare(Object o1, Object o2) {
-        return o1.toString().substring(0, 1).compareTo(
-            o2.toString().substring(0, 1));
-      }
-
-      @Override
-      public int compare(byte[] arg0, int arg1, int arg2, byte[] arg3,
-          int arg4, int arg5) {
-        throw new RuntimeException("Not implemented");
-      }  
-    };
-    
-    // value order comparator - order by second character
-    RawComparator orderComparator = new RawComparator() {
-      @Override
-      public int compare(Object o1, Object o2) {
-        return o1.toString().substring(1, 2).compareTo(
-            o2.toString().substring(1, 2));
-      }
-      
-      @Override
-      public int compare(byte[] arg0, int arg1, int arg2, byte[] arg3,
-          int arg4, int arg5) {
-        throw new RuntimeException("Not implemented");
-      }
-    };
-    
-    // reducer to track the order of the input values using bit shifting
-    driver.withReducer(new Reducer<Text, LongWritable, Text, LongWritable>() {
-      @Override
-      public void reduce(Text key, Iterator<LongWritable> values,
-          OutputCollector<Text, LongWritable> output, Reporter reporter)
-          throws IOException {
-        long outputValue = 0;
-        int count = 0;
-        while (values.hasNext()) {
-          outputValue |= (values.next().get() << (count++*8));
-        }
-        
-        output.collect(key, new LongWritable(outputValue));
-      }
-
-      @Override
-      public void configure(JobConf job) {}
-
-      @Override
-      public void close() throws IOException {}
-    });
-    
-    driver.withKeyGroupingComparator(groupComparator);
-    driver.withKeyOrderComparator(orderComparator);
-    
-    driver.addInput(new Text("a1"), new LongWritable(1));
-    driver.addInput(new Text("b1"), new LongWritable(1));
-    driver.addInput(new Text("a3"), new LongWritable(3));
-    driver.addInput(new Text("a2"), new LongWritable(2));
-    
-    driver.addOutput(new Text("a1"), new LongWritable(0x1 | (0x2 << 8) | (0x3 << 16)));
-    driver.addOutput(new Text("b1"), new LongWritable(0x1));
-    
-    driver.runTest();
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestPipelineMapReduceDriver.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestPipelineMapReduceDriver.java
deleted file mode 100644
index b7faac2..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestPipelineMapReduceDriver.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-import static org.apache.hadoop.mrunit.testutil.ExtendedAssert.assertListEquals;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.Reducer;
-import org.apache.hadoop.mapred.lib.IdentityMapper;
-import org.apache.hadoop.mapred.lib.IdentityReducer;
-import org.apache.hadoop.mapred.lib.LongSumReducer;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.junit.Test;
-
-public class TestPipelineMapReduceDriver extends TestCase {
-
-  private static final int FOO_IN_A = 42;
-  private static final int FOO_IN_B = 10;
-  private static final int BAR_IN   = 12;
-  private static final int FOO_OUT  = 52;
-  private static final int BAR_OUT  = 12;
-
-  @Test
-  public void testFullyEmpty() throws IOException {
-    // If no mappers or reducers are configured, then it should
-    // just return its inputs. If there are no inputs, this
-    // should be an empty list of outputs.
-    PipelineMapReduceDriver driver = new PipelineMapReduceDriver();
-    List out = driver.run();
-    assertEquals("Expected empty output list", out.size(), 0);
-  }
-
-  @Test
-  public void testEmptyPipeline() throws IOException {
-    // If no mappers or reducers are configured, then it should
-    // just return its inputs.
-    PipelineMapReduceDriver driver = new PipelineMapReduceDriver();
-    driver.addInput(new Text("foo"), new Text("bar"));
-    List out = driver.run();
-
-    List expected = new ArrayList();
-    expected.add(new Pair<Text, Text>(new Text("foo"), new Text("bar")));
-    assertListEquals(expected, out);
-  }
-
-  @Test
-  public void testEmptyPipelineWithRunTest() {
-    // Like testEmptyPipeline, but call runTest.
-    PipelineMapReduceDriver driver = new PipelineMapReduceDriver();
-    driver.withInput(new Text("foo"), new Text("bar"))
-          .withOutput(new Text("foo"), new Text("bar"))
-          .runTest();
-  }
-
-
-  @Test
-  public void testSingleIdentity() {
-    // Test that an identity mapper and identity reducer work
-    PipelineMapReduceDriver driver = new PipelineMapReduceDriver();
-    driver.withMapReduce(new IdentityMapper(), new IdentityReducer())
-          .withInput(new Text("foo"), new Text("bar"))
-          .withOutput(new Text("foo"), new Text("bar"))
-          .runTest();
-  }
-
-  @Test
-  public void testMultipleIdentities() {
-    // Test that a pipeline of identity mapper and reducers work
-    PipelineMapReduceDriver driver = new PipelineMapReduceDriver();
-    driver.withMapReduce(new IdentityMapper(), new IdentityReducer())
-          .withMapReduce(new IdentityMapper(), new IdentityReducer())
-          .withMapReduce(new IdentityMapper(), new IdentityReducer())
-          .withInput(new Text("foo"), new Text("bar"))
-          .withOutput(new Text("foo"), new Text("bar"))
-          .runTest();
-  }
-
-  @Test
-  public void testSumAtEnd() {
-    PipelineMapReduceDriver driver = new PipelineMapReduceDriver();
-    driver.withMapReduce(new IdentityMapper(), new IdentityReducer())
-          .withMapReduce(new IdentityMapper(), new IdentityReducer())
-          .withMapReduce(new IdentityMapper(), new LongSumReducer())
-          .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-          .withInput(new Text("bar"), new LongWritable(BAR_IN))
-          .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-          .withOutput(new Text("bar"), new LongWritable(BAR_OUT))
-          .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-          .runTest();
-  }
-
-  @Test
-  public void testSumInMiddle() {
-    PipelineMapReduceDriver driver = new PipelineMapReduceDriver();
-    driver.withMapReduce(new IdentityMapper(), new IdentityReducer())
-          .withMapReduce(new IdentityMapper(), new LongSumReducer())
-          .withMapReduce(new IdentityMapper(), new IdentityReducer())
-          .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-          .withInput(new Text("bar"), new LongWritable(BAR_IN))
-          .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-          .withOutput(new Text("bar"), new LongWritable(BAR_OUT))
-          .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-          .runTest();
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestReduceDriver.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestReduceDriver.java
deleted file mode 100644
index 3174e41..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestReduceDriver.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-import static org.apache.hadoop.mrunit.testutil.ExtendedAssert.assertListEquals;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.MapReduceBase;
-import org.apache.hadoop.mapred.OutputCollector;
-import org.apache.hadoop.mapred.Reducer;
-import org.apache.hadoop.mapred.Reporter;
-import org.apache.hadoop.mapred.lib.LongSumReducer;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestReduceDriver extends TestCase {
-
-  private static final int IN_A = 4;
-  private static final int IN_B = 6;
-  private static final int OUT_VAL = 10;
-  private static final int INCORRECT_OUT = 12;
-  private static final int OUT_EMPTY = 0;
-
-  private Reducer<Text, LongWritable, Text, LongWritable> reducer;
-  private ReduceDriver<Text, LongWritable, Text, LongWritable> driver;
-
-  @Before
-  public void setUp() throws Exception {
-    reducer = new LongSumReducer<Text>();
-    driver = new ReduceDriver<Text, LongWritable, Text, LongWritable>(
-                   reducer);
-  }
-
-  @Test
-  public void testRun() {
-    List<Pair<Text, LongWritable>> out = null;
-
-    try {
-      out = driver.withInputKey(new Text("foo"))
-                  .withInputValue(new LongWritable(IN_A))
-                  .withInputValue(new LongWritable(IN_B))
-                  .run();
-    } catch (IOException ioe) {
-      fail();
-    }
-
-    List<Pair<Text, LongWritable>> expected =
-        new ArrayList<Pair<Text, LongWritable>>();
-    expected.add(new Pair<Text, LongWritable>(new Text("foo"),
-            new LongWritable(OUT_VAL)));
-
-    assertListEquals(out, expected);
-
-  }
-
-  @Test
-  public void testTestRun1() {
-    driver
-            .withInputKey(new Text("foo"))
-            .withOutput(new Text("foo"), new LongWritable(0))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun2() {
-    driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun3() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("bar"), new LongWritable(OUT_VAL))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-
-  }
-
-  @Test
-  public void testTestRun4() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(INCORRECT_OUT))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun5() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(IN_A))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun6() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(IN_A))
-            .withOutput(new Text("foo"), new LongWritable(IN_B))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun7() {
-    try {
-      driver
-              .withInputKey(new Text("foo"))
-              .withInputValue(new LongWritable(IN_A))
-              .withInputValue(new LongWritable(IN_B))
-              .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-              .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-              .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun8() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("bar"), new LongWritable(OUT_VAL))
-            .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-            .runTest();
-            fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun9() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-            .withOutput(new Text("bar"), new LongWritable(OUT_VAL))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testEmptyInput() {
-    // (null, <empty>) will be forcibly fed as input
-    // since we use LongSumReducer, expect (null, 0) out.
-    driver
-            .withOutput(null, new LongWritable(OUT_EMPTY))
-            .runTest();
-  }
-
-  @Test
-  public void testEmptyInput2() {
-    // because a null key with zero inputs will be fed as input
-    // to this reducer, do not accept no outputs.
-    try {
-      driver.runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  /**
-   * Reducer that counts its values twice; the second iteration
-   * according to mapreduce semantics should be empty.
-   */
-  private static class DoubleIterReducer<K, V>
-      extends MapReduceBase implements Reducer<K, V, K, LongWritable> {
-    public void reduce(K key, Iterator<V> values,
-        OutputCollector<K, LongWritable> out, Reporter r) throws IOException {
-      long count = 0;
-
-      while (values.hasNext()) {
-        count++;
-        values.next();
-      }
-
-      // This time around, iteration should yield no values.
-      while (values.hasNext()) {
-        count++;
-        values.next();
-      }
-      out.collect(key, new LongWritable(count));
-    }
-  }
-
-  @Test
-  public void testDoubleIteration() {
-    reducer = new DoubleIterReducer<Text, LongWritable>();
-    driver = new ReduceDriver<Text, LongWritable, Text, LongWritable>(
-        reducer);
-
-    driver
-        .withInputKey(new Text("foo"))
-        .withInputValue(new LongWritable(1))
-        .withInputValue(new LongWritable(1))
-        .withInputValue(new LongWritable(1))
-        .withInputValue(new LongWritable(1))
-        .withOutput(new Text("foo"), new LongWritable(4))
-        .runTest();
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestTestDriver.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestTestDriver.java
deleted file mode 100644
index 4336977..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/TestTestDriver.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit;
-
-import static org.apache.hadoop.mrunit.testutil.ExtendedAssert.assertListEquals;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.junit.Test;
-
-public class TestTestDriver extends TestCase {
-
-  /**
-   * Test method for
-   * {@link org.apache.hadoop.mrunit.TestDriver#parseTabbedPair(java.lang.String)}.
-   */
-  @Test
-  public void testParseTabbedPair1() {
-    Pair<Text, Text> pr = TestDriver.parseTabbedPair("foo\tbar");
-    assertEquals(pr.getFirst().toString(), "foo");
-    assertEquals(pr.getSecond().toString(), "bar");
-  }
-
-  @Test
-  public void testParseTabbedPair2() {
-    Pair<Text, Text> pr = TestDriver.parseTabbedPair("   foo\tbar");
-    assertEquals(pr.getFirst().toString(), "   foo");
-    assertEquals(pr.getSecond().toString(), "bar");
-  }
-
-  @Test
-  public void testParseTabbedPair3() {
-    Pair<Text, Text> pr = TestDriver.parseTabbedPair("foo\tbar   ");
-    assertEquals(pr.getFirst().toString(), "foo");
-    assertEquals(pr.getSecond().toString(), "bar   ");
-  }
-
-  @Test
-  public void testParseTabbedPair4() {
-    Pair<Text, Text> pr = TestDriver.parseTabbedPair("foo    \tbar");
-    assertEquals(pr.getFirst().toString(), "foo    ");
-    assertEquals(pr.getSecond().toString(), "bar");
-  }
-
-  @Test
-  public void testParseTabbedPair5() {
-    Pair<Text, Text> pr = TestDriver.parseTabbedPair("foo\t  bar");
-    assertEquals(pr.getFirst().toString(), "foo");
-    assertEquals(pr.getSecond().toString(), "  bar");
-  }
-
-  @Test
-  public void testParseTabbedPair6() {
-    Pair<Text, Text> pr = TestDriver.parseTabbedPair("foo\t\tbar");
-    assertEquals(pr.getFirst().toString(), "foo");
-    assertEquals(pr.getSecond().toString(), "\tbar");
-  }
-
-  @Test
-  public void testParseTabbedPair7() {
-    Pair<Text, Text> pr = TestDriver.parseTabbedPair("foo\tbar\n");
-    assertEquals(pr.getFirst().toString(), "foo");
-    assertEquals(pr.getSecond().toString(), "bar\n");
-  }
-
-  @Test
-  public void testParseTabbedPair8() {
-    Pair<Text, Text> pr = TestDriver.parseTabbedPair("foo\t  bar\tbaz");
-    assertEquals(pr.getFirst().toString(), "foo");
-    assertEquals(pr.getSecond().toString(), "  bar\tbaz");
-  }
-
-  /**
-   * Test method for
-   * {@link
-   * org.apache.hadoop.mrunit.TestDriver#parseCommaDelimitedList(java.lang.String)}.
-   */
-  @Test
-  public void testParseCommaDelimList1() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    assertListEquals(out, verify);
-  }
-
-  @Test
-  public void testParseCommaDelimList2() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo,bar");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    assertListEquals(out, verify);
-  }
-
-  @Test
-  public void testParseCommaDelimList3() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo   ,bar");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    assertListEquals(out, verify);
-  }
-
-  @Test
-  public void testParseCommaDelimList4() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo,   bar");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    assertListEquals(out, verify);
-  }
-
-  @Test
-  public void testParseCommaDelimList5() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("   foo,bar");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    assertListEquals(out, verify);
-  }
-
-  @Test
-  public void testParseCommaDelimList6() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo,bar   ");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    assertListEquals(out, verify);
-  }
-
-  @Test
-  public void testParseCommaDelimList7() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo,bar, baz");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    verify.add(new Text("baz"));
-    assertListEquals(out, verify);
-  }
-
-  // note: we decide that correct behavior is that this does *not*
-  // add a tailing empty element by itself.
-  @Test
-  public void testParseCommaDelimList8() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo,bar,");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    assertListEquals(out, verify);
-  }
-
-  // but this one does.
-  @Test
-  public void testParseCommaDelimList8a() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo,bar,,");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    verify.add(new Text(""));
-    assertListEquals(out, verify);
-  }
-
-  @Test
-  public void testParseCommaDelimList9() {
-    List<Text> out = TestDriver.parseCommaDelimitedList("foo,,bar");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text("foo"));
-    verify.add(new Text(""));
-    verify.add(new Text("bar"));
-    assertListEquals(out, verify);
-  }
-
-  @Test
-  public void testParseCommaDelimList10() {
-    List<Text> out = TestDriver.parseCommaDelimitedList(",foo,bar");
-    ArrayList<Text> verify = new ArrayList<Text>();
-    verify.add(new Text(""));
-    verify.add(new Text("foo"));
-    verify.add(new Text("bar"));
-    assertListEquals(out, verify);
-  }
-
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/AllTests.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/AllTests.java
deleted file mode 100644
index 7514ee5..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/AllTests.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * All tests for the new 0.20+ mapreduce API versions of the test harness.
- */
-public final class AllTests  {
-
-  private AllTests() { }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Test for org.apache.hadoop.mrunit.mapreduce");
-
-    suite.addTestSuite(TestMapDriver.class);
-    suite.addTestSuite(TestReduceDriver.class);
-    suite.addTestSuite(TestMapReduceDriver.class);
-    suite.addTestSuite(TestCounters.class);
-
-    return suite;
-  }
-
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestCounters.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestCounters.java
deleted file mode 100644
index 3fc3e65..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestCounters.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapreduce.Counters;
-import org.apache.hadoop.mapreduce.Mapper;
-import org.apache.hadoop.mapreduce.Reducer;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test counters usage in various drivers.
- */
-public class TestCounters extends TestCase {
-
-  private static final String GROUP = "GROUP";
-  private static final String ELEM = "ELEM";
-
-  private class CounterMapper extends Mapper<Text, Text, Text, Text> {
-    public void map(Text k, Text v, Context context)
-        throws IOException, InterruptedException {
-
-      context.getCounter(GROUP, ELEM).increment(1);
-
-      // Emit the same (k, v) pair twice.
-      context.write(k, v);
-      context.write(k, v);
-    }
-  }
-
-  private class CounterReducer extends Reducer<Text, Text, Text, Text> {
-    public void reduce(Text k, Iterable<Text> vals, Context context)
-        throws IOException, InterruptedException {
-
-      for(Text val : vals) {
-        context.getCounter(GROUP, ELEM).increment(1);
-        context.write(k, val);
-      }
-    }
-  }
-
-  @Test
-  public void testMapper() throws IOException {
-    Mapper<Text, Text, Text, Text> mapper = new CounterMapper();
-    MapDriver<Text, Text, Text, Text> driver = new MapDriver<Text, Text, Text, Text>(mapper);
-    driver.withInput(new Text("foo"), new Text("bar")).run();
-    assertEquals("Expected 1 counter increment", 1,
-        driver.getCounters().findCounter(GROUP, ELEM).getValue());
-  }
-
-  @Test
-  public void testReducer() throws IOException {
-    Reducer<Text, Text, Text, Text> reducer = new CounterReducer();
-    ReduceDriver<Text, Text, Text, Text> driver = new ReduceDriver<Text, Text, Text, Text>(reducer);
-    driver.withInputKey(new Text("foo"))
-          .withInputValue(new Text("bar"))
-          .run();
-    assertEquals("Expected 1 counter increment", 1,
-        driver.getCounters().findCounter(GROUP, ELEM).getValue());
-  }
-
-  @Test
-  public void testMapReduce() throws IOException {
-    Mapper<Text, Text, Text, Text> mapper = new CounterMapper();
-    Reducer<Text, Text, Text, Text> reducer = new CounterReducer();
-    MapReduceDriver<Text, Text, Text, Text, Text, Text> driver =
-        new MapReduceDriver<Text, Text, Text, Text, Text, Text>(mapper, reducer);
-
-    driver.withInput(new Text("foo"), new Text("bar"))
-          .run();
-
-    assertEquals("Expected counter=3", 3,
-        driver.getCounters().findCounter(GROUP, ELEM).getValue());
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestMapDriver.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestMapDriver.java
deleted file mode 100644
index ff07395..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestMapDriver.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce;
-
-import static org.apache.hadoop.mrunit.testutil.ExtendedAssert.*;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.io.NullWritable;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapreduce.Mapper;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestMapDriver extends TestCase {
-
-  private Mapper<Text, Text, Text, Text> mapper;
-  private MapDriver<Text, Text, Text, Text> driver;
-
-  @Before
-  public void setUp() {
-    mapper = new Mapper<Text, Text, Text, Text>(); // default action is identity mapper.
-    driver = new MapDriver<Text, Text, Text, Text>(mapper);
-  }
-
-  @Test
-  public void testRun() {
-    List<Pair<Text, Text>> out = null;
-
-    try {
-      out = driver.withInput(new Text("foo"), new Text("bar")).run();
-    } catch (IOException ioe) {
-      fail();
-    }
-
-    List<Pair<Text, Text>> expected = new ArrayList<Pair<Text, Text>>();
-    expected.add(new Pair<Text, Text>(new Text("foo"), new Text("bar")));
-
-    assertListEquals(out, expected);
-  }
-
-  @Test
-  public void testTestRun1() {
-    driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun2() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun3() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun4() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("bonusfoo"), new Text("bar"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-
-  }
-  @Test
-  public void testTestRun5() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("somethingelse"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun6() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-              .withOutput(new Text("someotherkey"), new Text("bar"))
-              .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun7() {
-    try {
-      driver.withInput(new Text("foo"), new Text("bar"))
-            .withOutput(new Text("someotherkey"), new Text("bar"))
-            .withOutput(new Text("foo"), new Text("bar"))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testSetInput() {
-    try {
-      driver.setInput(new Pair<Text, Text>(new Text("foo"), new Text("bar")));
-    } catch (Exception e) {
-      fail();
-    }
-
-    assertEquals(driver.getInputKey(), new Text("foo"));
-    assertEquals(driver.getInputValue(), new Text("bar"));
-  }
-
-  @Test
-  public void testSetInputNull() {
-    try {
-      driver.setInput((Pair<Text, Text>) null);
-      fail();
-    } catch (Exception e) {
-      // expect this.
-    }
-  }
-
-  @Test
-  public void testEmptyInput() {
-    // MapDriver will forcibly map (null, null) as undefined input;
-    // identity mapper expects (null, null) back.
-    driver.withOutput(null, null).runTest();
-  }
-
-  @Test
-  public void testEmptyInput2() {
-    // it is an error to expect no output because we expect
-    // the mapper to be fed (null, null) as an input if the
-    // user doesn't set any input.
-    try {
-      driver.runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-  
-  @Test
-  public void testConfiguration() {
-	  Configuration conf = new Configuration();
-	  conf.set("TestKey", "TestValue");
-	  MapDriver<NullWritable, NullWritable, NullWritable, NullWritable> confDriver 
-	      = new MapDriver<NullWritable, NullWritable, NullWritable, NullWritable>();
-	  ConfigurationMapper<NullWritable, NullWritable, NullWritable, NullWritable> mapper 
-	      = new ConfigurationMapper<NullWritable, NullWritable, NullWritable, NullWritable>();
-	  confDriver.withMapper(mapper).withConfiguration(conf).
-	      withInput(NullWritable.get(),NullWritable.get()).
-	      withOutput(NullWritable.get(),NullWritable.get()).runTest();
-	  assertEquals(mapper.setupConfiguration.get("TestKey"), "TestValue");
-  }
-
-  /**
-   * Test mapper which stores the configuration object it was passed during its setup method
-   */
-  public static class ConfigurationMapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> extends Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
-	public Configuration setupConfiguration;
-	
-	@Override
-	protected void setup(Context context) throws IOException,
-			InterruptedException {
-		setupConfiguration = context.getConfiguration();
-	}
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestMapReduceDriver.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestMapReduceDriver.java
deleted file mode 100644
index 5f63d4c..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestMapReduceDriver.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce;
-
-import static org.apache.hadoop.mrunit.testutil.ExtendedAssert.assertListEquals;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.io.NullWritable;
-import org.apache.hadoop.io.RawComparator;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.JobConf;
-import org.apache.hadoop.mapred.OutputCollector;
-import org.apache.hadoop.mapred.Reporter;
-import org.apache.hadoop.mapreduce.Mapper;
-import org.apache.hadoop.mapreduce.Reducer;
-import org.apache.hadoop.mapreduce.Reducer.Context;
-import org.apache.hadoop.mapreduce.lib.reduce.LongSumReducer;
-import org.apache.hadoop.mrunit.mapreduce.TestMapDriver.ConfigurationMapper;
-import org.apache.hadoop.mrunit.mapreduce.TestReduceDriver.ConfigurationReducer;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestMapReduceDriver extends TestCase {
-
-  private static final int FOO_IN_A = 42;
-  private static final int FOO_IN_B = 10;
-  private static final int BAR_IN = 12;
-  private static final int FOO_OUT = 52;
-
-  private Mapper<Text, LongWritable, Text, LongWritable> mapper;
-  private Reducer<Text, LongWritable, Text, LongWritable> reducer;
-  private MapReduceDriver<Text, LongWritable,
-                  Text, LongWritable,
-                  Text, LongWritable> driver;
-
-  private MapReduceDriver<Text, Text, Text, Text, Text, Text> driver2;
-
-  @Before
-  public void setUp() throws Exception {
-    mapper = new Mapper<Text, LongWritable, Text, LongWritable>(); // This is the IdentityMapper
-    reducer = new LongSumReducer<Text>();
-    driver = new MapReduceDriver<Text, LongWritable,
-                                 Text, LongWritable,
-                                 Text, LongWritable>(
-                        mapper, reducer);
-    // for shuffle tests
-    driver2 = new MapReduceDriver<Text, Text, Text, Text, Text, Text>();
-  }
-
-  @Test
-  public void testRun() {
-    List<Pair<Text, LongWritable>> out = null;
-    try {
-      out = driver
-              .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-              .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-              .withInput(new Text("bar"), new LongWritable(BAR_IN))
-              .run();
-    } catch (IOException ioe) {
-      fail();
-    }
-
-    List<Pair<Text, LongWritable>> expected =
-      new ArrayList<Pair<Text, LongWritable>>();
-    expected.add(new Pair<Text, LongWritable>(new Text("bar"),
-            new LongWritable(BAR_IN)));
-    expected.add(new Pair<Text, LongWritable>(new Text("foo"),
-            new LongWritable(FOO_OUT)));
-
-    assertListEquals(out, expected);
-  }
-
-  @Test
-  public void testTestRun1() {
-    driver
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun2() {
-    driver
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun3() {
-    try {
-      driver
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_A))
-            .withInput(new Text("bar"), new LongWritable(BAR_IN))
-            .withInput(new Text("foo"), new LongWritable(FOO_IN_B))
-            .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-            .withOutput(new Text("bar"), new LongWritable(BAR_IN))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected
-    }
-  }
-
-  @Test
-  public void testEmptyInput() {
-    driver.runTest();
-  }
-
-  @Test
-  public void testEmptyInputWithOutputFails() {
-    try {
-      driver
-              .withOutput(new Text("foo"), new LongWritable(FOO_OUT))
-              .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testEmptyShuffle() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-    assertEquals(0, outputs.size());
-  }
-
-  // just shuffle a single (k, v) pair
-  @Test
-  public void testSingleShuffle() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("b")));
-
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-
-    List<Pair<Text, List<Text>>> expected = new ArrayList<Pair<Text, List<Text>>>();
-    List<Text> sublist = new ArrayList<Text>();
-    sublist.add(new Text("b"));
-    expected.add(new Pair<Text, List<Text>>(new Text("a"), sublist));
-
-    assertListEquals(expected, outputs);
-  }
-
-  // shuffle multiple values from the same key.
-  @Test
-  public void testShuffleOneKey() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("b")));
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("c")));
-
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-
-    List<Pair<Text, List<Text>>> expected = new ArrayList<Pair<Text, List<Text>>>();
-    List<Text> sublist = new ArrayList<Text>();
-    sublist.add(new Text("b"));
-    sublist.add(new Text("c"));
-    expected.add(new Pair<Text, List<Text>>(new Text("a"), sublist));
-
-    assertListEquals(expected, outputs);
-  }
-
-  // shuffle multiple keys
-  @Test
-  public void testMultiShuffle1() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("x")));
-    inputs.add(new Pair<Text, Text>(new Text("b"), new Text("z")));
-    inputs.add(new Pair<Text, Text>(new Text("b"), new Text("w")));
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("y")));
-
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-
-    List<Pair<Text, List<Text>>> expected = new ArrayList<Pair<Text, List<Text>>>();
-    List<Text> sublist1 = new ArrayList<Text>();
-    sublist1.add(new Text("x"));
-    sublist1.add(new Text("y"));
-    expected.add(new Pair<Text, List<Text>>(new Text("a"), sublist1));
-
-    List<Text> sublist2 = new ArrayList<Text>();
-    sublist2.add(new Text("z"));
-    sublist2.add(new Text("w"));
-    expected.add(new Pair<Text, List<Text>>(new Text("b"), sublist2));
-
-    assertListEquals(expected, outputs);
-  }
-
-
-  // shuffle multiple keys that are out-of-order to start.
-  @Test
-  public void testMultiShuffle2() {
-    List<Pair<Text, Text>> inputs = new ArrayList<Pair<Text, Text>>();
-    inputs.add(new Pair<Text, Text>(new Text("b"), new Text("z")));
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("x")));
-    inputs.add(new Pair<Text, Text>(new Text("b"), new Text("w")));
-    inputs.add(new Pair<Text, Text>(new Text("a"), new Text("y")));
-
-    List<Pair<Text, List<Text>>> outputs = driver2.shuffle(inputs);
-
-    List<Pair<Text, List<Text>>> expected = new ArrayList<Pair<Text, List<Text>>>();
-    List<Text> sublist1 = new ArrayList<Text>();
-    sublist1.add(new Text("x"));
-    sublist1.add(new Text("y"));
-    expected.add(new Pair<Text, List<Text>>(new Text("a"), sublist1));
-
-    List<Text> sublist2 = new ArrayList<Text>();
-    sublist2.add(new Text("z"));
-    sublist2.add(new Text("w"));
-    expected.add(new Pair<Text, List<Text>>(new Text("b"), sublist2));
-
-    assertListEquals(expected, outputs);
-  }
-  
-  @Test
-  public void testConfiguration() {
-	  Configuration conf = new Configuration();
-	  conf.set("TestKey", "TestValue");
-	  
-	  MapReduceDriver<NullWritable, NullWritable, NullWritable, NullWritable, NullWritable, NullWritable> confDriver 
-	      = new MapReduceDriver<NullWritable, NullWritable, NullWritable, NullWritable, NullWritable, NullWritable>();
-	  
-	  ConfigurationMapper<NullWritable, NullWritable, NullWritable, NullWritable> mapper 
-	      = new ConfigurationMapper<NullWritable, NullWritable, NullWritable, NullWritable>();
-	  ConfigurationReducer<NullWritable, NullWritable, NullWritable, NullWritable> reducer 
-      = new ConfigurationReducer<NullWritable, NullWritable, NullWritable, NullWritable>();
-	  
-	  confDriver.withMapper(mapper).withReducer(reducer).withConfiguration(conf).
-	      withInput(NullWritable.get(),NullWritable.get()).
-	      withOutput(NullWritable.get(),NullWritable.get()).runTest();
-	  assertEquals(mapper.setupConfiguration.get("TestKey"), "TestValue");
-	  assertEquals(reducer.setupConfiguration.get("TestKey"), "TestValue");	  
-  }
-
-  // Test the key grouping and value ordering comparators
-  @Test
-  public void testComparators() {
-    // group comparator - group by first character
-    RawComparator groupComparator = new RawComparator() {
-      @Override
-      public int compare(Object o1, Object o2) {
-        return o1.toString().substring(0, 1).compareTo(
-            o2.toString().substring(0, 1));
-      }
-
-      @Override
-      public int compare(byte[] arg0, int arg1, int arg2, byte[] arg3,
-          int arg4, int arg5) {
-        throw new RuntimeException("Not implemented");
-      }  
-    };
-    
-    // value order comparator - order by second character
-    RawComparator orderComparator = new RawComparator() {
-      @Override
-      public int compare(Object o1, Object o2) {
-        return o1.toString().substring(1, 2).compareTo(
-            o2.toString().substring(1, 2));
-      }
-      
-      @Override
-      public int compare(byte[] arg0, int arg1, int arg2, byte[] arg3,
-          int arg4, int arg5) {
-        throw new RuntimeException("Not implemented");
-      }
-    };
-    
-    // reducer to track the order of the input values using bit shifting
-    driver.withReducer(new Reducer<Text, LongWritable, Text, LongWritable>() {
-      protected void reduce(Text key, Iterable<LongWritable> values, Context context)
-          throws IOException, InterruptedException {
-        long outputValue = 0;
-        int count = 0;
-        for (LongWritable value : values) {
-          outputValue |= (value.get() << (count++*8));
-        }
-        
-        context.write(key, new LongWritable(outputValue));
-      }
-    });
-    
-    driver.withKeyGroupingComparator(groupComparator);
-    driver.withKeyOrderComparator(orderComparator);
-    
-    driver.addInput(new Text("a1"), new LongWritable(1));
-    driver.addInput(new Text("b1"), new LongWritable(1));
-    driver.addInput(new Text("a3"), new LongWritable(3));
-    driver.addInput(new Text("a2"), new LongWritable(2));
-    
-    driver.addOutput(new Text("a1"), new LongWritable(0x1 | (0x2 << 8) | (0x3 << 16)));
-    driver.addOutput(new Text("b1"), new LongWritable(0x1));
-    
-    driver.runTest();
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestReduceDriver.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestReduceDriver.java
deleted file mode 100644
index bd5e38a..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mapreduce/TestReduceDriver.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mapreduce;
-
-import static org.apache.hadoop.mrunit.testutil.ExtendedAssert.assertListEquals;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.io.NullWritable;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapreduce.Mapper;
-import org.apache.hadoop.mapreduce.Reducer;
-import org.apache.hadoop.mapreduce.Mapper.Context;
-import org.apache.hadoop.mapreduce.lib.reduce.LongSumReducer;
-import org.apache.hadoop.mrunit.mapreduce.TestMapDriver.ConfigurationMapper;
-import org.apache.hadoop.mrunit.types.Pair;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestReduceDriver extends TestCase {
-
-  private static final int IN_A = 4;
-  private static final int IN_B = 6;
-  private static final int OUT_VAL = 10;
-  private static final int INCORRECT_OUT = 12;
-  private static final int OUT_EMPTY = 0;
-
-  private Reducer<Text, LongWritable, Text, LongWritable> reducer;
-  private ReduceDriver<Text, LongWritable, Text, LongWritable> driver;
-
-  @Before
-  public void setUp() throws Exception {
-    reducer = new LongSumReducer<Text>();
-    driver = new ReduceDriver<Text, LongWritable, Text, LongWritable>(
-                   reducer);
-  }
-
-  @Test
-  public void testRun() {
-    List<Pair<Text, LongWritable>> out = null;
-
-    try {
-      out = driver.withInputKey(new Text("foo"))
-                  .withInputValue(new LongWritable(IN_A))
-                  .withInputValue(new LongWritable(IN_B))
-                  .run();
-    } catch (IOException ioe) {
-      fail();
-    }
-
-    List<Pair<Text, LongWritable>> expected =
-        new ArrayList<Pair<Text, LongWritable>>();
-    expected.add(new Pair<Text, LongWritable>(new Text("foo"),
-            new LongWritable(OUT_VAL)));
-
-    assertListEquals(out, expected);
-
-  }
-
-  @Test
-  public void testTestRun1() {
-    driver
-            .withInputKey(new Text("foo"))
-            .withOutput(new Text("foo"), new LongWritable(0))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun2() {
-    driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-            .runTest();
-  }
-
-  @Test
-  public void testTestRun3() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("bar"), new LongWritable(OUT_VAL))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-
-  }
-
-  @Test
-  public void testTestRun4() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(INCORRECT_OUT))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun5() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(IN_A))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun6() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(IN_A))
-            .withOutput(new Text("foo"), new LongWritable(IN_B))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun7() {
-    try {
-      driver
-              .withInputKey(new Text("foo"))
-              .withInputValue(new LongWritable(IN_A))
-              .withInputValue(new LongWritable(IN_B))
-              .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-              .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-              .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun8() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("bar"), new LongWritable(OUT_VAL))
-            .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-            .runTest();
-            fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testTestRun9() {
-    try {
-      driver
-            .withInputKey(new Text("foo"))
-            .withInputValue(new LongWritable(IN_A))
-            .withInputValue(new LongWritable(IN_B))
-            .withOutput(new Text("foo"), new LongWritable(OUT_VAL))
-            .withOutput(new Text("bar"), new LongWritable(OUT_VAL))
-            .runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  @Test
-  public void testEmptyInput() {
-    // (null, <empty>) will be forcibly fed as input
-    // since we use LongSumReducer, expect (null, 0) out.
-    driver
-            .withOutput(null, new LongWritable(OUT_EMPTY))
-            .runTest();
-  }
-
-  @Test
-  public void testEmptyInput2() {
-    // because a null key with zero inputs will be fed as input
-    // to this reducer, do not accept no outputs.
-    try {
-      driver.runTest();
-      fail();
-    } catch (RuntimeException re) {
-      // expected.
-    }
-  }
-
-  /**
-   * Reducer that counts its values twice; the second iteration
-   * according to mapreduce semantics should be empty.
-   */
-  private static class DoubleIterReducer<K, V>
-      extends Reducer<K, V, K, LongWritable> {
-    public void reduce(K key, Iterable<V> values, Context c)
-        throws IOException, InterruptedException {
-      long count = 0;
-
-      for (V val : values) {
-        count++;
-      }
-
-      // This time around, iteration should yield no values.
-      for (V val : values) {
-        count++;
-      }
-      c.write(key, new LongWritable(count));
-    }
-  }
-
-  @Test
-  public void testDoubleIteration() {
-    reducer = new DoubleIterReducer<Text, LongWritable>();
-    driver = new ReduceDriver<Text, LongWritable, Text, LongWritable>(
-        reducer);
-
-    driver
-        .withInputKey(new Text("foo"))
-        .withInputValue(new LongWritable(1))
-        .withInputValue(new LongWritable(1))
-        .withInputValue(new LongWritable(1))
-        .withInputValue(new LongWritable(1))
-        .withOutput(new Text("foo"), new LongWritable(4))
-        .runTest();
-  }
-  
-  @Test
-  public void testConfiguration() {
-	  Configuration conf = new Configuration();
-	  conf.set("TestKey", "TestValue");
-	  ReduceDriver<NullWritable, NullWritable, NullWritable, NullWritable> confDriver 
-	      = new ReduceDriver<NullWritable, NullWritable, NullWritable, NullWritable>();
-	  ConfigurationReducer<NullWritable, NullWritable, NullWritable, NullWritable> reducer 
-	      = new ConfigurationReducer<NullWritable, NullWritable, NullWritable, NullWritable>();
-	  confDriver.withReducer(reducer).withConfiguration(conf).
-	      withInput(NullWritable.get(),Arrays.asList(NullWritable.get())).
-	      withOutput(NullWritable.get(),NullWritable.get()).runTest();
-	  assertEquals(reducer.setupConfiguration.get("TestKey"), "TestValue");
-  }
-
-  /**
-   * Test reducer which stores the configuration object it was passed during its setup method
-   */
-  public static class ConfigurationReducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT> extends Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
-	public Configuration setupConfiguration;
-	
-	@Override
-	protected void setup(Context context) throws IOException,
-			InterruptedException {
-		setupConfiguration = context.getConfiguration();
-	}
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mock/TestMockOutputCollector.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mock/TestMockOutputCollector.java
deleted file mode 100644
index 1a2ad57..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mock/TestMockOutputCollector.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mock;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapred.Mapper;
-import org.apache.hadoop.mapred.MapReduceBase;
-import org.apache.hadoop.mapred.OutputCollector;
-import org.apache.hadoop.mapred.Reporter;
-import org.apache.hadoop.mrunit.MapDriver;
-
-import org.junit.Test;
-
-
-public class TestMockOutputCollector extends TestCase {
-
-  /**
-   * A mapper that reuses the same key and val objects to emit multiple values
-   */
-  class RepeatMapper extends MapReduceBase implements Mapper<Text, Text, Text, Text> {
-    public void map(Text k, Text v, OutputCollector<Text, Text> out, Reporter r)
-        throws IOException {
-      Text outKey = new Text();
-      Text outVal = new Text();
-
-      outKey.set("1");
-      outVal.set("a");
-      out.collect(outKey, outVal);
-
-      outKey.set("2");
-      outVal.set("b");
-      out.collect(outKey, outVal);
-
-      outKey.set("3");
-      outVal.set("c");
-      out.collect(outKey, outVal);
-    }
-  }
-
-  @Test
-  public void testRepeatedObjectUse() {
-    Mapper<Text, Text, Text, Text> mapper = new RepeatMapper();
-    MapDriver<Text, Text, Text, Text> driver = new MapDriver(mapper);
-
-    driver.withInput(new Text("inK"), new Text("inV"))
-          .withOutput(new Text("1"), new Text("a"))
-          .withOutput(new Text("2"), new Text("b"))
-          .withOutput(new Text("3"), new Text("c"))
-          .runTest();
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mock/TestMockReporter.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mock/TestMockReporter.java
deleted file mode 100644
index 2ade217..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/mock/TestMockReporter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.mock;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.mapred.InputSplit;
-import org.junit.Test;
-
-
-public class TestMockReporter extends TestCase {
-
-  @Test
-  public void testGetInputSplitForMapper() {
-    InputSplit split = new MockReporter(MockReporter.ReporterType.Mapper, null).getInputSplit();
-    assertTrue(null != split);
-  }
-
-  // reporter is contractually obligated to throw an exception
-  // if the reducer tries to grab the input split.
-  @Test
-  public void testGetInputSplitForReducer() {
-    try {
-      new MockReporter(MockReporter.ReporterType.Reducer, null).getInputSplit();
-      fail(); // shouldn't get here
-    } catch (UnsupportedOperationException uoe) {
-      // expected this.
-    }
-  }
-}
-
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/types/AllTests.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/types/AllTests.java
deleted file mode 100644
index d760ba3..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/types/AllTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.types;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * Test suite for all type objects in the common library
- *
- */
-public final class AllTests {
-
-  private AllTests() { }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Test for org.apache.hadoop.mrunit.types");
-
-    suite.addTestSuite(TestPair.class);
-    return suite;
-  }
-}
diff --git a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/types/TestPair.java b/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/types/TestPair.java
deleted file mode 100644
index 0073c44..0000000
--- a/src/contrib/mrunit/src/test/org/apache/hadoop/mrunit/types/TestPair.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.hadoop.mrunit.types;
-
-import junit.framework.TestCase;
-
-import org.junit.Test;
-
-public class TestPair extends TestCase {
-
-  public static final int VAL_A = 3;
-  public static final int VAL_B = 4;
-  public static final int VAL_C = 65;
-  public static final int VAL_D = 98;
-
-  /**
-   * Test method for
-   * {@link
-   * org.apache.hadoop.mrunit.types.Pair#equals(org.apache.hadoop.mrunit.types.Pair)}.
-   */
-  @Test
-  public void testEqualsTrulyEqual() {
-    assertTrue(
-      new Pair<Integer, Integer>(Integer.valueOf(VAL_A), Integer.valueOf(VAL_B))
-      .equals(new Pair<Integer, Integer>(
-              Integer.valueOf(VAL_A), Integer.valueOf(VAL_B))));
-  }
-
-  @Test
-  public void testEqualsInequalFirst() {
-    assertFalse(new Pair<Integer, Integer>(
-                Integer.valueOf(VAL_A), Integer.valueOf(VAL_B))
-            .equals(new Pair<Integer, Integer>(Integer.valueOf(VAL_C),
-                    Integer.valueOf(VAL_B))));
-  }
-
-  @Test
-  public void testEqualsInequalSecond() {
-    assertFalse(new Pair<Integer, Integer>(
-                Integer.valueOf(VAL_A), Integer.valueOf(VAL_B))
-            .equals(new Pair<Integer, Integer>(Integer.valueOf(VAL_A),
-                    Integer.valueOf(VAL_D))));
-  }
-
-  @Test
-  public void testEqualsNullNull() {
-    assertTrue(new Pair<Integer, Integer>(null, null)
-            .equals(new Pair<Integer, Integer>(null, null)));
-  }
-
-  @Test
-  public void testEqualsNullIntFirst0() {
-    assertTrue(new Pair<Integer, Integer>(Integer.valueOf(VAL_A), null)
-            .equals(new Pair<Integer, Integer>(Integer.valueOf(VAL_A), null)));
-  }
-
-  @Test
-  public void testEqualsNullIntFirst1() {
-    assertFalse(new Pair<Integer, Integer>(null, null)
-            .equals(new Pair<Integer, Integer>(Integer.valueOf(VAL_A), null)));
-  }
-
-  @Test
-  public void testEqualsNullIntFirst2() {
-    assertFalse(new Pair<Integer, Integer>(Integer.valueOf(VAL_A), null)
-            .equals(new Pair<Integer, Integer>(null, null)));
-  }
-
-  @Test
-  public void testEqualsNullIntSecond0() {
-    assertTrue(new Pair<Integer, Integer>(null, Integer.valueOf(VAL_A))
-            .equals(new Pair<Integer, Integer>(null, Integer.valueOf(VAL_A))));
-  }
-
-  @Test
-  public void testEqualsNullIntSecond1() {
-    assertFalse(new Pair<Integer, Integer>(null, null)
-            .equals(new Pair<Integer, Integer>(null, Integer.valueOf(VAL_A))));
-  }
-
-  @Test
-  public void testEqualsNullIntSecond2() {
-    assertFalse(new Pair<Integer, Integer>(null, Integer.valueOf(VAL_A))
-            .equals(new Pair<Integer, Integer>(null, null)));
-  }
-
-  /**
-   * Test method for
-   * {@link
-   * org.apache.hadoop.mrunit.types.Pair#compareTo(org.apache.hadoop.mrunit.types.Pair)}.
-   */
-  @Test
-  public void testCompareToTrulyEqual() {
-    assertTrue(0 == new Pair<Integer, Integer>(Integer.valueOf(VAL_A),
-                                               Integer.valueOf(VAL_B))
-            .compareTo(new Pair<Integer, Integer>(Integer.valueOf(VAL_A),
-                    Integer.valueOf(VAL_B))));
-  }
-
-  @Test
-  public void testCompareToInequalFirst() {
-    assertFalse(0 == new Pair<Integer, Integer>(Integer.valueOf(VAL_A),
-            Integer.valueOf(VAL_B)).compareTo(
-                new Pair<Integer, Integer>(Integer.valueOf(
-                                           VAL_C), Integer.valueOf(VAL_B))));
-  }
-
-  @Test
-  public void testCompareToInequalSecond() {
-    assertFalse(0 == new Pair<Integer, Integer>(Integer.valueOf(VAL_A),
-            Integer.valueOf(VAL_B)).compareTo(
-            new Pair<Integer, Integer>(Integer.valueOf(VAL_A),
-                                       Integer.valueOf(VAL_D))));
-  }
-
-  @Test
-  public void testCompareToNullNull() {
-    try {
-      new Pair<Integer, Integer>(null, null)
-              .compareTo(new Pair<Integer, Integer>(null, null));
-      fail();
-    } catch (NullPointerException npe) {
-      // expected this; ok.
-    }
-  }
-
-  @Test
-  public void testCompareToNullIntFirst0() {
-    try {
-      new Pair<Integer, Integer>(Integer.valueOf(VAL_A), null)
-          .compareTo(new Pair<Integer, Integer>(Integer.valueOf(VAL_A), null));
-      fail();
-    } catch (NullPointerException npe) {
-      // expected this; ok.
-    }
-  }
-
-  @Test
-  public void testCompareToNullIntFirst1() {
-    try {
-      new Pair<Integer, Integer>(null, null)
-          .compareTo(new Pair<Integer, Integer>(Integer.valueOf(VAL_A), null));
-      fail();
-    } catch (NullPointerException npe) {
-      // expected this; ok.
-    }
-  }
-
-  @Test
-  public void testCompareToNullIntFirst2() {
-    try {
-      new Pair<Integer, Integer>(Integer.valueOf(VAL_A), null)
-          .compareTo(new Pair<Integer, Integer>(null, null));
-      fail();
-    } catch (NullPointerException npe) {
-      // expected this; ok.
-    }
-  }
-
-  @Test
-  public void testCompareToNullIntSecond0() {
-    try {
-      new Pair<Integer, Integer>(null, Integer.valueOf(VAL_A))
-          .compareTo(new Pair<Integer, Integer>(null, Integer.valueOf(VAL_A)));
-      fail();
-    } catch (NullPointerException npe) {
-      // expected this; ok.
-    }
-  }
-
-  @Test
-  public void testCompareToNullIntSecond1() {
-    try {
-      new Pair<Integer, Integer>(null, null)
-          .compareTo(new Pair<Integer, Integer>(null, Integer.valueOf(VAL_A)));
-      fail();
-    } catch (NullPointerException npe) {
-      // expected this; ok.
-    }
-  }
-
-  @Test
-  public void testCompareToNullIntSecond2() {
-    try {
-      new Pair<Integer, Integer>(null, Integer.valueOf(VAL_A))
-          .compareTo(new Pair<Integer, Integer>(null, null));
-      fail();
-    } catch (NullPointerException npe) {
-      // expected this; ok.
-    }
-  }
-
-}
