http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ReopenReaderTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ReopenReaderTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReopenReaderTask.cs
new file mode 100644
index 0000000..eeb8f8c
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReopenReaderTask.cs
@@ -0,0 +1,45 @@
+using Lucene.Net.Index;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Reopens <see cref="IndexReader"/> and closes old <see 
cref="IndexReader"/>.
+    /// </summary>
+    public class ReopenReaderTask : PerfTask
+    {
+        public ReopenReaderTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            DirectoryReader r = RunData.GetIndexReader();
+            DirectoryReader nr = DirectoryReader.OpenIfChanged(r);
+            if (nr != null)
+            {
+                RunData.SetIndexReader(nr);
+                nr.DecRef();
+            }
+            r.DecRef();
+            return 1;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepAllTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepAllTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepAllTask.cs
new file mode 100644
index 0000000..e382605
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepAllTask.cs
@@ -0,0 +1,83 @@
+using Lucene.Net.Benchmarks.ByTask.Stats;
+using Lucene.Net.Support;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Report all statistics with no aggregations.
+    /// <para/>
+    /// Other side effects: None.
+    /// </summary>
+    public class RepAllTask : ReportTask
+    {
+        public RepAllTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            Report rp = ReportAll(RunData.Points.TaskStats);
+
+            SystemConsole.WriteLine();
+            SystemConsole.WriteLine("------------> Report All (" + rp.Count + 
" out of " + rp.OutOf + ")");
+            SystemConsole.WriteLine(rp.Text);
+            SystemConsole.WriteLine();
+            return 0;
+        }
+
+        /// <summary>
+        /// Report detailed statistics as a string.
+        /// </summary>
+        /// <param name="taskStats"></param>
+        /// <returns>The report.</returns>
+        protected virtual Report ReportAll(IList<TaskStats> taskStats)
+        {
+            string longestOp = LongestOp(taskStats);
+            bool first = true;
+            StringBuilder sb = new StringBuilder();
+            sb.Append(TableTitle(longestOp));
+            sb.Append(newline);
+            int reported = 0;
+            foreach (TaskStats stat in taskStats)
+            {
+                if (stat.Elapsed >= 0)
+                { // consider only tasks that ended
+                    if (!first)
+                    {
+                        sb.Append(newline);
+                    }
+                    first = false;
+                    string line = TaskReportLine(longestOp, stat);
+                    reported++;
+                    if (taskStats.Count > 2 && reported % 2 == 0)
+                    {
+                        line = line.Replace("   ", " - ");
+                    }
+                    sb.Append(line);
+                }
+            }
+            string reptxt = (reported == 0 ? "No Matching Entries Were Found!" 
: sb.ToString());
+            return new Report(reptxt, reported, reported, taskStats.Count);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSelectByPrefTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSelectByPrefTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSelectByPrefTask.cs
new file mode 100644
index 0000000..16aac93
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSelectByPrefTask.cs
@@ -0,0 +1,81 @@
+using Lucene.Net.Benchmarks.ByTask.Stats;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Report by-name-prefix statistics with no aggregations.
+    /// <para/>
+    /// Other side effects: None.
+    /// </summary>
+    public class RepSelectByPrefTask : RepSumByPrefTask
+    {
+        public RepSelectByPrefTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            Report rp = ReportSelectByPrefix(RunData.Points.TaskStats);
+
+            SystemConsole.WriteLine();
+            SystemConsole.WriteLine("------------> Report Select By Prefix (" 
+ m_prefix + ") (" +
+                rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + 
")");
+            SystemConsole.WriteLine(rp.Text);
+            SystemConsole.WriteLine();
+
+            return 0;
+        }
+
+        protected virtual Report ReportSelectByPrefix(IList<TaskStats> 
taskStats)
+        {
+            string longestOp = LongestOp(taskStats);
+            bool first = true;
+            StringBuilder sb = new StringBuilder();
+            sb.Append(TableTitle(longestOp));
+            sb.Append(newline);
+            int reported = 0;
+            foreach (TaskStats stat in taskStats)
+            {
+                if (stat.Elapsed >= 0 && 
stat.Task.GetName().StartsWith(m_prefix, StringComparison.Ordinal))
+                { // only ended tasks with proper name
+                    reported++;
+                    if (!first)
+                    {
+                        sb.Append(newline);
+                    }
+                    first = false;
+                    string line = TaskReportLine(longestOp, stat);
+                    if (taskStats.Count > 2 && reported % 2 == 0)
+                    {
+                        line = line.Replace("   ", " - ");
+                    }
+                    sb.Append(line);
+                }
+            }
+            string reptxt = (reported == 0 ? "No Matching Entries Were Found!" 
: sb.ToString());
+            return new Report(reptxt, reported, reported, taskStats.Count);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameRoundTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameRoundTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameRoundTask.cs
new file mode 100644
index 0000000..bce47ca
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameRoundTask.cs
@@ -0,0 +1,83 @@
+using Lucene.Net.Benchmarks.ByTask.Stats;
+using Lucene.Net.Support;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Report all statistics grouped/aggregated by name and round.
+    /// <para/>
+    /// Other side effects: None.
+    /// </summary>
+    public class RepSumByNameRoundTask : ReportTask
+    {
+        public RepSumByNameRoundTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            Report rp = ReportSumByNameRound(RunData.Points.TaskStats);
+
+            SystemConsole.WriteLine();
+            SystemConsole.WriteLine("------------> Report Sum By (any) Name 
and Round (" +
+                rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + 
")");
+            SystemConsole.WriteLine(rp.Text);
+            SystemConsole.WriteLine();
+
+            return 0;
+        }
+
+        /// <summary>
+        /// Report statistics as a string, aggregate for tasks named the same, 
and from the same round.
+        /// </summary>
+        /// <param name="taskStats"></param>
+        /// <returns>The report.</returns>
+        protected virtual Report ReportSumByNameRound(IList<TaskStats> 
taskStats)
+        {
+            // aggregate by task name and round
+            LinkedHashMap<string, TaskStats> p2 = new LinkedHashMap<string, 
TaskStats>();
+            int reported = 0;
+            foreach (TaskStats stat1 in taskStats)
+            {
+                if (stat1.Elapsed >= 0)
+                { // consider only tasks that ended
+                    reported++;
+                    string name = stat1.Task.GetName();
+                    string rname = stat1.Round + "." + name; // group by round
+                    TaskStats stat2;
+                    if (!p2.TryGetValue(rname, out stat2) || stat2 == null)
+                    {
+                        stat2 = (TaskStats)stat1.Clone();
+
+                        p2[rname] = stat2;
+                    }
+                    else
+                    {
+                        stat2.Add(stat1);
+                    }
+                }
+            }
+            // now generate report from secondary list p2    
+            return GenPartialReport(reported, p2, taskStats.Count);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameTask.cs
new file mode 100644
index 0000000..30d9878
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameTask.cs
@@ -0,0 +1,81 @@
+using Lucene.Net.Benchmarks.ByTask.Stats;
+using Lucene.Net.Support;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Report all statistics aggregated by name.
+    /// <para/>
+    /// Other side effects: None.
+    /// </summary>
+    public class RepSumByNameTask : ReportTask
+    {
+        public RepSumByNameTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            Report rp = ReportSumByName(RunData.Points.TaskStats);
+
+            SystemConsole.WriteLine();
+            SystemConsole.WriteLine("------------> Report Sum By (any) Name (" 
+
+                rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + 
")");
+            SystemConsole.WriteLine(rp.Text);
+            SystemConsole.WriteLine();
+
+            return 0;
+        }
+
+        /// <summary>
+        /// Report statistics as a string, aggregate for tasks named the same.
+        /// </summary>
+        /// <param name="taskStats"></param>
+        /// <returns>The report.</returns>
+        protected virtual Report ReportSumByName(IList<TaskStats> taskStats)
+        {
+            // aggregate by task name
+            int reported = 0;
+            LinkedHashMap<string, TaskStats> p2 = new LinkedHashMap<string, 
TaskStats>();
+            foreach (TaskStats stat1 in taskStats)
+            {
+                if (stat1.Elapsed >= 0)
+                { // consider only tasks that ended
+                    reported++;
+                    string name = stat1.Task.GetName();
+                    TaskStats stat2;
+                    if (!p2.TryGetValue(name, out stat2) || stat2 == null)
+                    {
+                        stat2 = (TaskStats)stat1.Clone();
+                        p2[name] = stat2;
+                    }
+                    else
+                    {
+                        stat2.Add(stat1);
+                    }
+                }
+            }
+            // now generate report from secondary list p2    
+            return GenPartialReport(reported, p2, taskStats.Count);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefRoundTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefRoundTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefRoundTask.cs
new file mode 100644
index 0000000..ce977a0
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefRoundTask.cs
@@ -0,0 +1,79 @@
+using Lucene.Net.Benchmarks.ByTask.Stats;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Report all prefix matching statistics grouped/aggregated by name and 
round.
+    /// <para/>
+    /// Other side effects: None.
+    /// </summary>
+    public class RepSumByPrefRoundTask : RepSumByPrefTask
+    {
+        public RepSumByPrefRoundTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            Report rp = ReportSumByPrefixRound(RunData.Points.TaskStats);
+
+            Console.Out.WriteLine();
+            Console.Out.WriteLine("------------> Report sum by Prefix (" + 
m_prefix + ") and Round (" +
+                rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + 
")");
+            Console.Out.WriteLine(rp.Text);
+            Console.Out.WriteLine();
+
+            return 0;
+        }
+
+        protected virtual Report ReportSumByPrefixRound(IList<TaskStats> 
taskStats)
+        {
+            // aggregate by task name and by round
+            int reported = 0;
+            LinkedHashMap<string, TaskStats> p2 = new LinkedHashMap<string, 
TaskStats>();
+            foreach (TaskStats stat1 in taskStats)
+            {
+                if (stat1.Elapsed >= 0 && 
stat1.Task.GetName().StartsWith(m_prefix, StringComparison.Ordinal))
+                { // only ended tasks with proper name
+                    reported++;
+                    string name = stat1.Task.GetName();
+                    string rname = stat1.Round + "." + name; // group by round
+                    TaskStats stat2;
+                    if (!p2.TryGetValue(rname, out stat2) || stat2 == null)
+                    {
+                        stat2 = (TaskStats)stat1.Clone();
+
+                        p2[rname] = stat2;
+                    }
+                    else
+                    {
+                        stat2.Add(stat1);
+                    }
+                }
+            }
+            // now generate report from secondary list p2    
+            return GenPartialReport(reported, p2, taskStats.Count);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefTask.cs
new file mode 100644
index 0000000..732e902
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefTask.cs
@@ -0,0 +1,91 @@
+using Lucene.Net.Benchmarks.ByTask.Stats;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Report by-name-prefix statistics aggregated by name.
+    /// <para/>
+    /// Other side effects: None.
+    /// </summary>
+    public class RepSumByPrefTask : ReportTask
+    {
+        public RepSumByPrefTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        protected string m_prefix;
+
+        public override int DoLogic()
+        {
+            Report rp = ReportSumByPrefix(RunData.Points.TaskStats);
+
+            SystemConsole.WriteLine();
+            SystemConsole.WriteLine("------------> Report Sum By Prefix (" + 
m_prefix + ") (" +
+                rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + 
")");
+            SystemConsole.WriteLine(rp.Text);
+            SystemConsole.WriteLine();
+
+            return 0;
+        }
+
+        protected virtual Report ReportSumByPrefix(IList<TaskStats> taskStats)
+        {
+            // aggregate by task name
+            int reported = 0;
+            LinkedHashMap<string, TaskStats> p2 = new LinkedHashMap<string, 
TaskStats>();
+            foreach (TaskStats stat1 in taskStats)
+            {
+                if (stat1.Elapsed >= 0 && 
stat1.Task.GetName().StartsWith(m_prefix, StringComparison.Ordinal))
+                { // only ended tasks with proper name
+                    reported++;
+                    string name = stat1.Task.GetName();
+                    TaskStats stat2;
+                    if (!p2.TryGetValue(name, out stat2) || stat2 == null)
+                    {
+                        stat2 = (TaskStats)stat1.Clone();
+                        p2[name] = stat2;
+                    }
+                    else
+                    {
+                        stat2.Add(stat1);
+                    }
+                }
+            }
+            // now generate report from secondary list p2    
+            return GenPartialReport(reported, p2, taskStats.Count);
+        }
+
+
+        public virtual void SetPrefix(string prefix)
+        {
+            this.m_prefix = prefix;
+        }
+
+        /// <seealso cref="PerfTask.ToString()"/>
+        public override string ToString()
+        {
+            return base.ToString() + " " + m_prefix;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ReportTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ReportTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReportTask.cs
new file mode 100644
index 0000000..0e83471
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReportTask.cs
@@ -0,0 +1,189 @@
+using Lucene.Net.Benchmarks.ByTask.Stats;
+using Lucene.Net.Benchmarks.ByTask.Utils;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Report (abstract) task - all report tasks extend this task.
+    /// </summary>
+    public abstract class ReportTask : PerfTask
+    {
+        public ReportTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        /// <seealso cref="PerfTask.ShouldNeverLogAtStart"/>
+        protected override bool ShouldNeverLogAtStart
+        {
+            get { return true; }
+        }
+
+        /// <seealso cref="PerfTask.ShouldNotRecordStats"/>
+        protected override bool ShouldNotRecordStats
+        {
+            get { return true; }
+        }
+
+        /// <summary>
+        /// From here start the code used to generate the reports.
+        /// Subclasses would use this part to generate reports.
+        /// </summary>
+        protected static readonly string newline = Environment.NewLine;
+
+        /// <summary>
+        /// Get a textual summary of the benchmark results, average from all 
test runs.
+        /// </summary>
+        protected static readonly string OP = "Operation  ";
+        protected static readonly string ROUND = " round";
+        protected static readonly string RUNCNT = "   runCnt";
+        protected static readonly string RECCNT = "   recsPerRun";
+        protected static readonly string RECSEC = "        rec/s";
+        protected static readonly string ELAPSED = "  elapsedSec";
+        protected static readonly string USEDMEM = "    avgUsedMem";
+        protected static readonly string TOTMEM = "    avgTotalMem";
+        protected static readonly string[] COLS = {
+            RUNCNT,
+            RECCNT,
+            RECSEC,
+            ELAPSED,
+            USEDMEM,
+            TOTMEM
+        };
+
+        /// <summary>
+        /// Compute a title line for a report table.
+        /// </summary>
+        /// <param name="longestOp">Size of longest op name in the 
table.</param>
+        /// <returns>The table title line.</returns>
+        protected virtual string TableTitle(string longestOp)
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.Append(Formatter.Format(OP, longestOp));
+            sb.Append(ROUND);
+            sb.Append(RunData.Config.GetColsNamesForValsByRound());
+            for (int i = 0; i < COLS.Length; i++)
+            {
+                sb.Append(COLS[i]);
+            }
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// Find the longest op name out of completed tasks.
+        /// </summary>
+        /// <param name="taskStats">Completed tasks to be considered.</param>
+        /// <returns>The longest op name out of completed tasks.</returns>
+        protected virtual string LongestOp(IEnumerable<TaskStats> taskStats)
+        {
+            string longest = OP;
+            foreach (TaskStats stat in taskStats)
+            {
+                if (stat.Elapsed >= 0)
+                { // consider only tasks that ended
+                    string name = stat.Task.GetName();
+                    if (name.Length > longest.Length)
+                    {
+                        longest = name;
+                    }
+                }
+            }
+            return longest;
+        }
+
+        /// <summary>
+        /// Compute a report line for the given task stat.
+        /// </summary>
+        /// <param name="longestOp">Size of longest op name in the 
table.</param>
+        /// <param name="stat">Task stat to be printed.</param>
+        /// <returns>The report line.</returns>
+        protected virtual string TaskReportLine(string longestOp, TaskStats 
stat)
+        {
+            PerfTask task = stat.Task;
+            StringBuilder sb = new StringBuilder();
+            sb.Append(Formatter.Format(task.GetName(), longestOp));
+            string round = (stat.Round >= 0 ? "" + stat.Round : "-");
+            sb.Append(Formatter.FormatPaddLeft(round, ROUND));
+            sb.Append(RunData.Config.GetColsValuesForValsByRound(stat.Round));
+            sb.Append(Formatter.Format(stat.NumRuns, RUNCNT));
+            sb.Append(Formatter.Format(stat.Count / stat.NumRuns, RECCNT));
+            long elapsed = (stat.Elapsed > 0 ? stat.Elapsed : 1); // assume at 
least 1ms
+            sb.Append(Formatter.Format(2, (float)(stat.Count * 1000.0 / 
elapsed), RECSEC));
+            sb.Append(Formatter.Format(2, (float)stat.Elapsed / 1000, 
ELAPSED));
+            sb.Append(Formatter.Format(0, (float)stat.MaxUsedMem / 
stat.NumRuns, USEDMEM));
+            sb.Append(Formatter.Format(0, (float)stat.MaxTotMem / 
stat.NumRuns, TOTMEM));
+            return sb.ToString();
+        }
+
+        protected virtual Report GenPartialReport(int reported, 
LinkedHashMap<string, TaskStats> partOfTasks, int totalSize)
+        {
+            string longetOp = LongestOp(partOfTasks.Values);
+            bool first = true;
+            StringBuilder sb = new StringBuilder();
+            sb.Append(TableTitle(longetOp));
+            sb.Append(newline);
+            int lineNum = 0;
+            foreach (TaskStats stat in partOfTasks.Values)
+            {
+                if (!first)
+                {
+                    sb.Append(newline);
+                }
+                first = false;
+                string line = TaskReportLine(longetOp, stat);
+                lineNum++;
+                if (partOfTasks.Count > 2 && lineNum % 2 == 0)
+                {
+                    line = line.Replace("   ", " - ");
+                }
+                sb.Append(line);
+                int[] byTime = stat.GetCountsByTime();
+                if (byTime != null)
+                {
+                    sb.Append(newline);
+                    int end = -1;
+                    for (int i = byTime.Length - 1; i >= 0; i--)
+                    {
+                        if (byTime[i] != 0)
+                        {
+                            end = i;
+                            break;
+                        }
+                    }
+                    if (end != -1)
+                    {
+                        sb.Append("  by time:");
+                        for (int i = 0; i < end; i++)
+                        {
+                            sb.Append(' ').Append(byTime[i]);
+                        }
+                    }
+                }
+            }
+
+            string reptxt = (reported == 0 ? "No Matching Entries Were Found!" 
: sb.ToString());
+            return new Report(reptxt, partOfTasks.Count, reported, totalSize);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetInputsTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetInputsTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetInputsTask.cs
new file mode 100644
index 0000000..ed6261f
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetInputsTask.cs
@@ -0,0 +1,43 @@
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Reset inputs so that the test run would behave, input wise, 
+    /// as if it just started. This affects e.g. the generation of docs and 
queries.
+    /// </summary>
+    public class ResetInputsTask : PerfTask
+    {
+        public ResetInputsTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            RunData.ResetInputs();
+            return 0;
+        }
+
+        /// <seealso cref="PerfTask.ShouldNotRecordStats"/>
+        protected override bool ShouldNotRecordStats
+        {
+            get { return true; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemEraseTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemEraseTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemEraseTask.cs
new file mode 100644
index 0000000..b8e854a
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemEraseTask.cs
@@ -0,0 +1,42 @@
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Reset all index and input data and call gc, erase index and dir, does 
NOT clear statistics.
+    /// <para/>
+    /// This contains ResetInputs.
+    /// <para/>
+    /// Other side effects: writers/readers nullified, deleted, closed.
+    /// Index is erased.
+    /// Directory is erased.
+    /// </summary>
+    public class ResetSystemEraseTask : ResetSystemSoftTask
+    {
+        public ResetSystemEraseTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            RunData.Reinit(true);
+            return 0;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemSoftTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemSoftTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemSoftTask.cs
new file mode 100644
index 0000000..5d2d4f5
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemSoftTask.cs
@@ -0,0 +1,41 @@
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Reset all index and input data and call gc, does NOT erase index/dir, 
does NOT clear statistics.
+    /// This contains ResetInputs.
+    /// <para/>
+    /// Other side effects: writers/readers nullified, closed.
+    /// Index is NOT erased.
+    /// Directory is NOT erased.
+    /// </summary>
+    public class ResetSystemSoftTask : ResetInputsTask
+    {
+        public ResetSystemSoftTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override int DoLogic()
+        {
+            RunData.Reinit(false);
+            return 0;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RollbackIndexTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RollbackIndexTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/RollbackIndexTask.cs
new file mode 100644
index 0000000..c189b93
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RollbackIndexTask.cs
@@ -0,0 +1,52 @@
+using Lucene.Net.Index;
+using Lucene.Net.Util;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Rollback the index writer.
+    /// </summary>
+    public class RollbackIndexTask : PerfTask
+    {
+        public RollbackIndexTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        //bool doWait = true; // LUCENENET: Not used
+
+        public override int DoLogic()
+        {
+            IndexWriter iw = RunData.IndexWriter;
+            if (iw != null)
+            {
+                // If infoStream was set to output to a file, close it.
+                InfoStream infoStream = iw.Config.InfoStream;
+                if (infoStream != null)
+                {
+                    infoStream.Dispose();
+                }
+                iw.Rollback();
+                RunData.IndexWriter = null;
+            }
+            return 1;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTask.cs
new file mode 100644
index 0000000..f7dd4b7
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTask.cs
@@ -0,0 +1,60 @@
+using Lucene.Net.Benchmarks.ByTask.Feeds;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Search task.
+    /// <para/>
+    /// Note: This task reuses the reader if it is already open. 
+    /// Otherwise a reader is opened at start and closed at the end.
+    /// </summary>
+    public class SearchTask : ReadTask
+    {
+        public SearchTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override bool WithRetrieve
+        {
+            get { return false; }
+        }
+
+        public override bool WithSearch
+        {
+            get { return true; }
+        }
+
+        public override bool WithTraverse
+        {
+            get { return false; }
+        }
+
+        public override bool WithWarm
+        {
+            get { return false; }
+        }
+
+        public override IQueryMaker GetQueryMaker()
+        {
+            return RunData.GetQueryMaker(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetHighlightTask.cs
----------------------------------------------------------------------
diff --git 
a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetHighlightTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetHighlightTask.cs
new file mode 100644
index 0000000..2d623b1
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetHighlightTask.cs
@@ -0,0 +1,188 @@
+using Lucene.Net.Analysis;
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Search.Highlight;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Search and Traverse and Retrieve docs task.  Highlight the fields in 
the retrieved documents.
+    /// </summary>
+    /// <remarks>
+    /// Uses the <see cref="SimpleHTMLFormatter"/> for formatting.
+    /// <para/>
+    /// Note: This task reuses the reader if it is already open.
+    /// Otherwise a reader is opened at start and closed at the end.
+    /// <para/>
+    /// Takes optional multivalued, comma separated param string as: 
+    /// <code>
+    /// size[&lt;traversal 
size&gt;],highlight[&lt;int&gt;],maxFrags[&lt;int&gt;],mergeContiguous[&lt;boolean&gt;],fields[name1;name2;...]
+    /// </code>
+    /// <list type="table">
+    ///     <item><term>traversal size</term><description>The number of hits 
to traverse, otherwise all will be traversed.</description></item>
+    ///     <item><term>highlight</term><description>The number of the hits to 
highlight.  Will always be less than or equal to traversal size.  Default is 
<see cref="int.MaxValue"/> (i.e. hits.Length).</description></item>
+    ///     <item><term>maxFrags</term><description>The maximum number of 
fragments to score by the highlighter.</description></item>
+    ///     <item><term>mergeContiguous</term><description><c>true</c> if 
contiguous fragments should be merged.</description></item>
+    ///     <item><term>fields</term><description>The fields to highlight.  If 
not specified all fields will be highlighted (or at least 
attempted).</description></item>
+    /// </list>
+    /// <para/>
+    /// Example:
+    /// <code>
+    /// "SearchHlgtSameRdr" 
SearchTravRetHighlight(size[10],highlight[10],mergeContiguous[true],maxFrags[3],fields[body])
 > : 1000
+    /// </code>
+    /// <para/>
+    /// Documents must be stored in order for this task to work.  
Additionally, term vector positions can be used as well.
+    /// <para/>
+    /// Other side effects: counts additional 1 (record) for each traversed 
hit,
+    /// and 1 more for each retrieved (non null) document and 1 for each 
fragment returned.
+    /// </remarks>
+    public class SearchTravRetHighlightTask : SearchTravTask
+    {
+        protected int m_numToHighlight = int.MaxValue;
+        protected bool m_mergeContiguous;
+        protected int m_maxFrags = 2;
+        protected ISet<string> m_paramFields = new HashSet<string>();
+        protected Highlighter m_highlighter;
+        protected int m_maxDocCharsToAnalyze;
+
+        public SearchTravRetHighlightTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override void Setup()
+        {
+            base.Setup();
+            //check to make sure either the doc is being stored
+            PerfRunData data = RunData;
+            if (data.Config.Get("doc.stored", false) == false)
+            {
+                throw new Exception("doc.stored must be set to true");
+            }
+            m_maxDocCharsToAnalyze = 
data.Config.Get("highlighter.maxDocCharsToAnalyze", 
Highlighter.DEFAULT_MAX_CHARS_TO_ANALYZE);
+        }
+
+        public override bool WithRetrieve
+        {
+            get { return true; }
+        }
+
+        public override int NumToHighlight
+        {
+            get { return m_numToHighlight; }
+        }
+
+        protected override BenchmarkHighlighter GetBenchmarkHighlighter(Query 
q)
+        {
+            m_highlighter = new Highlighter(new SimpleHTMLFormatter(), new 
QueryScorer(q));
+            m_highlighter.MaxDocCharsToAnalyze = m_maxDocCharsToAnalyze;
+            return new BenchmarkHighlighterAnonymousHelper(this, 
m_highlighter);
+        }
+
+        private class BenchmarkHighlighterAnonymousHelper : 
BenchmarkHighlighter
+        {
+            private readonly SearchTravRetHighlightTask outerInstance;
+            private readonly Highlighter highlighter;
+
+            public 
BenchmarkHighlighterAnonymousHelper(SearchTravRetHighlightTask outerInstance, 
Highlighter highlighter)
+            {
+                this.outerInstance = outerInstance;
+                this.highlighter = highlighter;
+            }
+            public override int DoHighlight(IndexReader reader, int doc, 
string field, Document document, Analyzer analyzer, string text)
+            {
+                TokenStream ts = TokenSources.GetAnyTokenStream(reader, doc, 
field, document, analyzer);
+                TextFragment[]
+                frag = highlighter.GetBestTextFragments(ts, text, 
outerInstance.m_mergeContiguous, outerInstance.m_maxFrags);
+                return frag != null ? frag.Length : 0;
+            }
+        }
+
+        protected override ICollection<string> GetFieldsToHighlight(Document 
document)
+        {
+            ICollection<string> result = base.GetFieldsToHighlight(document);
+            //if stored is false, then result will be empty, in which case 
just get all the param fields
+            if (m_paramFields.Count > 0 && result.Count > 0)
+            {
+                //result.RetainAll(paramFields);
+                var toRemove = new List<string>();
+                foreach (var e in result)
+                {
+                    if (!m_paramFields.Contains(e))
+                        toRemove.Add(e);
+                }
+                result.RemoveAll(toRemove);
+            }
+            else
+            {
+                result = m_paramFields;
+            }
+            return result;
+        }
+
+        public override void SetParams(string @params)
+        {
+            // can't call super because super doesn't understand our
+            // params syntax
+            this.m_params = @params;
+            string[] splits = @params.Split(',').TrimEnd();
+            for (int i = 0; i < splits.Length; i++)
+            {
+                if (splits[i].StartsWith("size[", StringComparison.Ordinal) == 
true)
+                {
+                    int len = "size[".Length;
+                    m_traversalSize = 
(int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), 
CultureInfo.InvariantCulture);
+                }
+                else if (splits[i].StartsWith("highlight[", 
StringComparison.Ordinal) == true)
+                {
+                    int len = "highlight[".Length;
+                    m_numToHighlight = 
(int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), 
CultureInfo.InvariantCulture);
+                }
+                else if (splits[i].StartsWith("maxFrags[", 
StringComparison.Ordinal) == true)
+                {
+                    int len = "maxFrags[".Length;
+                    m_maxFrags = (int)float.Parse(splits[i].Substring(len, 
(splits[i].Length - 1) - len), CultureInfo.InvariantCulture);
+                }
+                else if (splits[i].StartsWith("mergeContiguous[", 
StringComparison.Ordinal) == true)
+                {
+                    int len = "mergeContiguous[".Length;
+                    m_mergeContiguous = bool.Parse(splits[i].Substring(len, 
(splits[i].Length - 1) - len));
+                }
+                else if (splits[i].StartsWith("fields[", 
StringComparison.Ordinal) == true)
+                {
+                    m_paramFields = new HashSet<string>();
+                    int len = "fields[".Length;
+                    string fieldNames = splits[i].Substring(len, 
(splits[i].Length - 1) - len);
+                    string[] fieldSplits = fieldNames.Split(';').TrimEnd();
+                    for (int j = 0; j < fieldSplits.Length; j++)
+                    {
+                        m_paramFields.Add(fieldSplits[j]);
+                    }
+
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetLoadFieldSelectorTask.cs
----------------------------------------------------------------------
diff --git 
a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetLoadFieldSelectorTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetLoadFieldSelectorTask.cs
new file mode 100644
index 0000000..169a330
--- /dev/null
+++ 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetLoadFieldSelectorTask.cs
@@ -0,0 +1,85 @@
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Support;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Search and Traverse and Retrieve docs task using a
+    /// FieldVisitor loading only the requested fields.
+    /// </summary>
+    /// <remarks>
+    /// Note: This task reuses the reader if it is already open.
+    /// Otherwise a reader is opened at start and closed at the end.
+    /// <para/>
+    /// Takes optional param: comma separated list of Fields to load.
+    /// <para/>
+    /// Other side effects: counts additional 1 (record) for each traversed 
hit, 
+    /// and 1 more for each retrieved (non null) document.
+    /// </remarks>
+    public class SearchTravRetLoadFieldSelectorTask : SearchTravTask
+    {
+        protected ISet<string> m_fieldsToLoad;
+
+        public SearchTravRetLoadFieldSelectorTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override bool WithRetrieve
+        {
+            get { return true; }
+        }
+
+
+        protected override Document RetrieveDoc(IndexReader ir, int id)
+        {
+            if (m_fieldsToLoad == null)
+            {
+                return ir.Document(id);
+            }
+            else
+            {
+                DocumentStoredFieldVisitor visitor = new 
DocumentStoredFieldVisitor(m_fieldsToLoad);
+                ir.Document(id, visitor);
+                return visitor.Document;
+            }
+        }
+
+        public override void SetParams(string @params)
+        {
+            this.m_params = @params; // cannot just call super.setParams(), 
b/c it's params differ.
+            m_fieldsToLoad = new HashSet<string>();
+            for (StringTokenizer tokenizer = new StringTokenizer(@params, 
","); tokenizer.HasMoreTokens();)
+            {
+                string s = tokenizer.NextToken();
+                m_fieldsToLoad.Add(s);
+            }
+        }
+
+
+        /// <seealso cref="PerfTask.SupportsParams"/>
+        public override bool SupportsParams
+        {
+            get { return true; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetTask.cs
new file mode 100644
index 0000000..61d1436
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetTask.cs
@@ -0,0 +1,44 @@
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Search and Traverse and Retrieve docs task. 
+    /// </summary>
+    /// <remarks>
+    /// Note: This task reuses the reader if it is already open. 
+    /// Otherwise a reader is opened at start and closed at the end.
+    /// <para/>
+    /// Takes optional param: traversal size (otherwise all results are 
traversed).
+    /// <para/>
+    /// Other side effects: counts additional 1 (record) for each traversed 
hit,
+    /// and 1 more for each retrieved (non null) document.
+    /// </remarks>
+    public class SearchTravRetTask : SearchTravTask
+    {
+        public SearchTravRetTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override bool WithRetrieve
+        {
+            get { return true; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetVectorHighlightTask.cs
----------------------------------------------------------------------
diff --git 
a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetVectorHighlightTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetVectorHighlightTask.cs
new file mode 100644
index 0000000..0725c65
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetVectorHighlightTask.cs
@@ -0,0 +1,191 @@
+using Lucene.Net.Analysis;
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Search.VectorHighlight;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Search and Traverse and Retrieve docs task.  Highlight the fields in 
the retrieved documents by using <see cref="FastVectorHighlighter"/>.
+    /// </summary>
+    /// <remarks>
+    /// Note: This task reuses the reader if it is already open.
+    /// Otherwise a reader is opened at start and closed at the end.
+    /// <para/>
+    /// Takes optional multivalued, comma separated param string as:
+    /// <code>
+    /// size[&lt;traversal 
size&gt;],highlight[&lt;int&gt;],maxFrags[&lt;int&gt;],mergeContiguous[&lt;boolean&gt;],fields[name1;name2;...]
+    /// </code>
+    /// <list type="bullet">
+    ///     <item><term>traversal size</term><description>The number of hits 
to traverse, otherwise all will be traversed.</description></item>
+    ///     <item><term>highlight</term><description>The number of the hits to 
highlight.  Will always be less than or equal to traversal size.  Default is 
<see cref="int.MaxValue"/> (i.e. hits.Length).</description></item>
+    ///     <item><term>maxFrags</term><description>The maximum number of 
fragments to score by the highlighter.</description></item>
+    ///     <item><term>fragSize</term><description>The length of 
fragments.</description></item>
+    ///     <item><term>fields</term><description>The fields to highlight.  If 
not specified all fields will be highlighted (or at least 
attempted).</description></item>
+    /// </list>
+    /// <para/>
+    /// Example:
+    /// <code>
+    /// "SearchVecHlgtSameRdr" 
SearchTravRetVectorHighlight(size[10],highlight[10],maxFrags[3],fields[body]) > 
: 1000
+    /// </code>
+    /// <para/>
+    /// Fields must be stored and term vector offsets and positions in order 
must be true for this task to work.
+    /// <para/>
+    /// Other side effects: counts additional 1 (record) for each traversed 
hit,
+    /// and 1 more for each retrieved (non null) document and 1 for each 
fragment returned.
+    /// </remarks>
+    public class SearchTravRetVectorHighlightTask : SearchTravTask
+    {
+        protected int m_numToHighlight = int.MaxValue;
+        protected int m_maxFrags = 2;
+        protected int m_fragSize = 100;
+        protected ISet<string> m_paramFields = new HashSet<string>();
+        protected FastVectorHighlighter m_highlighter;
+
+        public SearchTravRetVectorHighlightTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override void Setup()
+        {
+            base.Setup();
+            //check to make sure either the doc is being stored
+            PerfRunData data = RunData;
+            if (data.Config.Get("doc.stored", false) == false)
+            {
+                throw new Exception("doc.stored must be set to true");
+            }
+            if (data.Config.Get("doc.term.vector.offsets", false) == false)
+            {
+                throw new Exception("doc.term.vector.offsets must be set to 
true");
+            }
+            if (data.Config.Get("doc.term.vector.positions", false) == false)
+            {
+                throw new Exception("doc.term.vector.positions must be set to 
true");
+            }
+        }
+
+        public override bool WithRetrieve
+        {
+            get { return true; }
+        }
+
+        public override int NumToHighlight
+        {
+            get { return m_numToHighlight; }
+        }
+
+        protected override BenchmarkHighlighter GetBenchmarkHighlighter(Query 
q)
+        {
+            m_highlighter = new FastVectorHighlighter(false, false);
+            Query myq = q;
+            return new BenchmarkHighlighterAnonymousHelper(this, 
m_highlighter, myq);
+        }
+
+        private class BenchmarkHighlighterAnonymousHelper : 
BenchmarkHighlighter
+        {
+            private readonly SearchTravRetVectorHighlightTask outerInstance;
+            private readonly FastVectorHighlighter highlighter;
+            private readonly Query myq;
+            public 
BenchmarkHighlighterAnonymousHelper(SearchTravRetVectorHighlightTask 
outerInstance, FastVectorHighlighter highlighter, Query myq)
+            {
+                this.outerInstance = outerInstance;
+                this.highlighter = highlighter;
+                this.myq = myq;
+            }
+            public override int DoHighlight(IndexReader reader, int doc, 
string field, Document document, Analyzer analyzer, string text)
+            {
+                FieldQuery fq = highlighter.GetFieldQuery(myq, reader);
+                string[] fragments = highlighter.GetBestFragments(fq, reader, 
doc, field, outerInstance.m_fragSize, outerInstance.m_maxFrags);
+                return fragments != null ? fragments.Length : 0;
+            }
+        }
+
+        protected override ICollection<string> GetFieldsToHighlight(Document 
document)
+        {
+            ICollection<string> result = base.GetFieldsToHighlight(document);
+            //if stored is false, then result will be empty, in which case 
just get all the param fields
+            if (m_paramFields.Count > 0 && result.Count > 0)
+            {
+                //result.RetainAll(paramFields);
+                var toRemove = new List<string>();
+                foreach (var e in result)
+                {
+                    if (!m_paramFields.Contains(e))
+                        toRemove.Add(e);
+                }
+                result.RemoveAll(toRemove);
+            }
+            else
+            {
+                result = m_paramFields;
+            }
+            return result;
+        }
+
+        public override void SetParams(string @params)
+        {
+            // can't call super because super doesn't understand our
+            // params syntax
+            string[] splits = @params.Split(',').TrimEnd();
+            for (int i = 0; i < splits.Length; i++)
+            {
+                if (splits[i].StartsWith("size[", StringComparison.Ordinal) == 
true)
+                {
+                    int len = "size[".Length;
+                    m_traversalSize = 
(int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), 
CultureInfo.InvariantCulture);
+                }
+                else if (splits[i].StartsWith("highlight[", 
StringComparison.Ordinal) == true)
+                {
+                    int len = "highlight[".Length;
+                    m_numToHighlight = 
(int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), 
CultureInfo.InvariantCulture);
+                }
+                else if (splits[i].StartsWith("maxFrags[", 
StringComparison.Ordinal) == true)
+                {
+                    int len = "maxFrags[".Length;
+                    m_maxFrags = (int)float.Parse(splits[i].Substring(len, 
(splits[i].Length - 1) - len), CultureInfo.InvariantCulture);
+                }
+                else if (splits[i].StartsWith("fragSize[", 
StringComparison.Ordinal) == true)
+                {
+                    int len = "fragSize[".Length;
+                    m_fragSize = (int)float.Parse(splits[i].Substring(len, 
(splits[i].Length - 1) - len), CultureInfo.InvariantCulture);
+                }
+                else if (splits[i].StartsWith("fields[", 
StringComparison.Ordinal) == true)
+                {
+                    m_paramFields = new HashSet<string>();
+                    int len = "fields[".Length;
+                    string fieldNames = splits[i].Substring(len, 
(splits[i].Length - 1) - len);
+                    string[] fieldSplits = fieldNames.Split(';').TrimEnd();
+                    for (int j = 0; j < fieldSplits.Length; j++)
+                    {
+                        m_paramFields.Add(fieldSplits[j]);
+                    }
+
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravTask.cs
new file mode 100644
index 0000000..a514411
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravTask.cs
@@ -0,0 +1,87 @@
+using Lucene.Net.Benchmarks.ByTask.Feeds;
+using System.Globalization;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Search and Traverse task.
+    /// </summary>
+    /// <remarks>
+    /// Note: This task reuses the reader if it is already open. 
+    /// Otherwise a reader is opened at start and closed at the end.
+    /// <para/>
+    /// Takes optional param: traversal size (otherwise all results are 
traversed).
+    /// <para/>
+    /// Other side effects: counts additional 1 (record) for each traversed 
hit.
+    /// </remarks>
+    public class SearchTravTask : ReadTask
+    {
+        protected int m_traversalSize = int.MaxValue;
+
+        public SearchTravTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override bool WithRetrieve
+        {
+            get { return false; }
+        }
+
+
+        public override bool WithSearch
+        {
+            get { return true; }
+        }
+
+        public override bool WithTraverse
+        {
+            get { return true; }
+        }
+
+        public override bool WithWarm
+        {
+            get { return false; }
+        }
+
+
+        public override IQueryMaker GetQueryMaker()
+        {
+            return RunData.GetQueryMaker(this);
+        }
+
+        public override int TraversalSize
+        {
+            get { return m_traversalSize; }
+        }
+
+        public override void SetParams(string @params)
+        {
+            base.SetParams(@params);
+            m_traversalSize = (int)float.Parse(@params, 
CultureInfo.InvariantCulture);
+        }
+
+        /// <seealso cref="PerfTask.SupportsParams"/>
+        public override bool SupportsParams
+        {
+            get { return true; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithCollectorTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithCollectorTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithCollectorTask.cs
new file mode 100644
index 0000000..b767b44
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithCollectorTask.cs
@@ -0,0 +1,99 @@
+using Lucene.Net.Benchmarks.ByTask.Feeds;
+using Lucene.Net.Benchmarks.ByTask.Utils;
+using Lucene.Net.Search;
+using System;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Does search w/ a custom collector
+    /// </summary>
+    public class SearchWithCollectorTask : SearchTask
+    {
+        protected string m_clnName;
+
+        public SearchWithCollectorTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        public override void Setup()
+        {
+            base.Setup();
+            //check to make sure either the doc is being stored
+            PerfRunData runData = RunData;
+            Config config = runData.Config;
+            m_clnName = config.Get("collector.class", "");
+        }
+
+        public override bool WithCollector
+        {
+            get { return true; }
+        }
+
+        protected override ICollector CreateCollector()
+        {
+            ICollector collector = null;
+            if (m_clnName.Equals("topScoreDocOrdered", 
StringComparison.OrdinalIgnoreCase) == true)
+            {
+                collector = TopScoreDocCollector.Create(NumHits, true);
+            }
+            else if (m_clnName.Equals("topScoreDocUnOrdered", 
StringComparison.OrdinalIgnoreCase) == true)
+            {
+                collector = TopScoreDocCollector.Create(NumHits, false);
+            }
+            else if (m_clnName.Length > 0)
+            {
+                collector = 
(ICollector)Activator.CreateInstance(Type.GetType(m_clnName));
+
+            }
+            else
+            {
+                collector = base.CreateCollector();
+            }
+            return collector;
+        }
+
+        public override IQueryMaker GetQueryMaker()
+        {
+            return RunData.GetQueryMaker(this);
+        }
+
+        public override bool WithRetrieve
+        {
+            get { return false; }
+        }
+
+        public override bool WithSearch
+        {
+            get { return true; }
+        }
+
+        public override bool WithTraverse
+        {
+            get { return false; }
+        }
+
+        public override bool WithWarm
+        {
+            get { return false; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithSortTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithSortTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithSortTask.cs
new file mode 100644
index 0000000..634f048
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithSortTask.cs
@@ -0,0 +1,157 @@
+using Lucene.Net.Benchmarks.ByTask.Feeds;
+using Lucene.Net.Search;
+using Lucene.Net.Support;
+using System;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Does sort search on specified field.
+    /// </summary>
+    public class SearchWithSortTask : ReadTask
+    {
+        private bool doScore = true;
+        private bool doMaxScore = true;
+        private Sort sort;
+
+        public SearchWithSortTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        /// <summary>
+        /// SortFields: field:type,field:type[,noscore][,nomaxscore]
+        /// <para/>
+        /// If noscore is present, then we turn off score tracking
+        /// in <see cref="TopFieldCollector"/>.
+        /// If nomaxscore is present, then we turn off maxScore tracking
+        /// in <see cref="TopFieldCollector"/>.
+        /// <para/>
+        /// name:string,page:int,subject:string
+        /// </summary>
+        public override void SetParams(string sortField)
+        {
+            base.SetParams(sortField);
+            string[] fields = sortField.Split(',').TrimEnd();
+            SortField[] sortFields = new SortField[fields.Length];
+            int upto = 0;
+            for (int i = 0; i < fields.Length; i++)
+            {
+                string field = fields[i];
+                SortField sortField0;
+                if (field.Equals("doc", StringComparison.Ordinal))
+                {
+                    sortField0 = SortField.FIELD_DOC;
+                }
+                else if (field.Equals("score", StringComparison.Ordinal))
+                {
+                    sortField0 = SortField.FIELD_SCORE;
+                }
+                else if (field.Equals("noscore", StringComparison.Ordinal))
+                {
+                    doScore = false;
+                    continue;
+                }
+                else if (field.Equals("nomaxscore", StringComparison.Ordinal))
+                {
+                    doMaxScore = false;
+                    continue;
+                }
+                else
+                {
+                    int index = field.LastIndexOf(':');
+                    string fieldName;
+                    string typeString;
+                    if (index != -1)
+                    {
+                        fieldName = field.Substring(0, index - 0);
+                        typeString = field.Substring(1 + index, field.Length - 
(1 + index));
+                    }
+                    else
+                    {
+                        throw new Exception("You must specify the sort type ie 
page:int,subject:string");
+                    }
+                    sortField0 = new SortField(fieldName, 
(SortFieldType)Enum.Parse(typeof(SortFieldType), typeString, true));
+                }
+                sortFields[upto++] = sortField0;
+            }
+
+            if (upto < sortFields.Length)
+            {
+                SortField[] newSortFields = new SortField[upto];
+                System.Array.Copy(sortFields, 0, newSortFields, 0, upto);
+                sortFields = newSortFields;
+            }
+            this.sort = new Sort(sortFields);
+        }
+
+        public override bool SupportsParams
+        {
+            get { return true; }
+        }
+
+        public override IQueryMaker GetQueryMaker()
+        {
+            return RunData.GetQueryMaker(this);
+        }
+
+        public override bool WithRetrieve
+        {
+            get { return false; }
+        }
+
+        public override bool WithSearch
+        {
+            get { return true; }
+        }
+
+        public override bool WithTraverse
+        {
+            get { return false; }
+        }
+
+        public override bool WithWarm
+        {
+            get { return false; }
+        }
+
+        public override bool WithScore
+        {
+            get { return doScore; }
+        }
+
+        public override bool WithMaxScore
+        {
+            get { return doMaxScore; }
+        }
+
+        public override Sort Sort
+        {
+            get
+            {
+                if (sort == null)
+                {
+                    throw new InvalidOperationException("No sort field was 
set");
+                }
+                return sort;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SetPropTask.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SetPropTask.cs 
b/src/Lucene.Net.Benchmark/ByTask/Tasks/SetPropTask.cs
new file mode 100644
index 0000000..abb66d2
--- /dev/null
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SetPropTask.cs
@@ -0,0 +1,71 @@
+using System;
+
+namespace Lucene.Net.Benchmarks.ByTask.Tasks
+{
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// Set a performance test configuration property.
+    /// A property may have a single value, or a sequence of values, separated 
by ":". 
+    /// If a sequence of values is specified, each time a new round starts, 
+    /// the next (cyclic) value is taken.
+    /// <para/>
+    /// Other side effects: none.
+    /// <para/>
+    /// Takes mandatory param: "name,value" pair. 
+    /// </summary>
+    /// <seealso cref="NewRoundTask"/>
+    public class SetPropTask : PerfTask
+    {
+        public SetPropTask(PerfRunData runData)
+            : base(runData)
+        {
+        }
+
+        private string name;
+        private string value;
+
+        public override int DoLogic()
+        {
+            if (name == null || value == null)
+            {
+                throw new Exception(GetName() + " - undefined name or value: 
name=" + name + " value=" + value);
+            }
+            RunData.Config.Set(name, value);
+            return 0;
+        }
+
+        /// <summary>
+        /// Set the params (property name and value).
+        /// </summary>
+        /// <param name="params">Property name and value separated by 
','.</param>
+        public override void SetParams(string @params)
+        {
+            base.SetParams(@params);
+            int k = @params.IndexOf(",");
+            name = @params.Substring(0, k - 0).Trim();
+            value = @params.Substring(k + 1).Trim();
+        }
+
+        /// <seealso cref="PerfTask.SupportsParams"/>
+        public override bool SupportsParams
+        {
+            get { return true; }
+        }
+    }
+}

Reply via email to