lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r916340 [1/3] - in /lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net: ./ FastVectorHighlighter.Net/ FastVectorHighlighter.Net/Properties/ Test/ Test/Properties/
Date Thu, 25 Feb 2010 16:32:11 GMT
Author: digy
Date: Thu Feb 25 16:32:11 2010
New Revision: 916340

URL: http://svn.apache.org/viewvc?rev=916340&view=rev
Log:
LUCENENET-342 FastVectorHighlighter.Net

Added:
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net.txt
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/BaseFragmentsBuilder.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj.user
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldFragList.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldPhraseList.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldQuery.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldTermStack.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragListBuilder.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragmentsBuilder.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Properties/
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Properties/AssemblyInfo.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/ScoreOrderFragmentsBuilder.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragListBuilder.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragmentsBuilder.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Support.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/package.html
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.sln
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/AbstractTestCase.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/FieldPhraseListTest.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/FieldQueryTest.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/FieldTermStackTest.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/IndexTimeSynonymTest.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/Properties/
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/Properties/AssemblyInfo.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/ScoreOrderFragmentsBuilderTest.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/SimpleFragListBuilderTest.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/SimpleFragmentsBuilderTest.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/Support.cs
    lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/Test/Test.csproj

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net.txt
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net.txt?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net.txt (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net.txt Thu Feb 25 16:32:11 2010
@@ -0,0 +1,3 @@
+
+Some internal fields/methods are made "public" to be able to use them in Test project. 
+Those fields/methods (starting with a lowercase char) are not intended to be used in your code.

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/BaseFragmentsBuilder.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/BaseFragmentsBuilder.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/BaseFragmentsBuilder.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/BaseFragmentsBuilder.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,138 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Lucene.Net.Documents;
+using Lucene.Net.Search;
+using Lucene.Net.Index;
+
+using WeightedFragInfo = Lucene.Net.Search.Vectorhighlight.FieldFragList.WeightedFragInfo;
+using SubInfo = Lucene.Net.Search.Vectorhighlight.FieldFragList.WeightedFragInfo.SubInfo;
+using Toffs = Lucene.Net.Search.Vectorhighlight.FieldPhraseList.WeightedPhraseInfo.Toffs;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    public abstract class BaseFragmentsBuilder : FragmentsBuilder
+    {
+        protected String[] preTags, postTags;
+        public static String[] COLORED_PRE_TAGS = {
+            "<b style=\"background:yellow\">", "<b style=\"background:lawngreen\">", "<b style=\"background:aquamarine\">",
+            "<b style=\"background:magenta\">", "<b style=\"background:palegreen\">", "<b style=\"background:coral\">",
+            "<b style=\"background:wheat\">", "<b style=\"background:khaki\">", "<b style=\"background:lime\">",
+            "<b style=\"background:deepskyblue\">"
+        };
+
+        public static String[] COLORED_POST_TAGS = { "</b>" };
+
+        protected BaseFragmentsBuilder() : this(new String[] { "<b>" }, new String[] { "</b>" })
+        {
+            
+        }
+
+        protected BaseFragmentsBuilder(String[] preTags, String[] postTags)
+        {
+            this.preTags = preTags;
+            this.postTags = postTags;
+        }
+
+        static Object CheckTagsArgument(Object tags)
+        {
+            if (tags is String) return tags;
+            else if (tags is String[]) return tags;
+            throw new ArgumentException("type of preTags/postTags must be a String or String[]");
+        }
+
+        public abstract List<WeightedFragInfo> GetWeightedFragInfoList(List<WeightedFragInfo> src);
+
+        public String CreateFragment(IndexReader reader, int docId, String fieldName, FieldFragList fieldFragList)
+        {
+            String[] fragments = CreateFragments(reader, docId, fieldName, fieldFragList, 1);
+            if (fragments == null || fragments.Length == 0) return null;
+            return fragments[0];
+        }
+
+        public String[] CreateFragments(IndexReader reader, int docId, String fieldName, FieldFragList fieldFragList, int maxNumFragments)
+        {
+            if (maxNumFragments < 0)
+                throw new ArgumentException("maxNumFragments(" + maxNumFragments + ") must be positive number.");
+
+            List<WeightedFragInfo> fragInfos = GetWeightedFragInfoList(fieldFragList.fragInfos);
+
+            List<String> fragments = new List<String>(maxNumFragments);
+            String[] values = GetFieldValues(reader, docId, fieldName);
+            if (values.Length == 0) return null;
+            StringBuilder buffer = new StringBuilder();
+            int[] nextValueIndex = { 0 };
+            for (int n = 0; n < maxNumFragments && n < fragInfos.Count; n++)
+            {
+                WeightedFragInfo fragInfo = fragInfos[n];
+                fragments.Add(MakeFragment(buffer, nextValueIndex, values, fragInfo));
+            }
+            return fragments.ToArray();
+        }
+
+        protected String[] GetFieldValues(IndexReader reader, int docId, String fieldName)
+        {
+            Document doc = reader.Document(docId, new MapFieldSelector(new String[] { fieldName }));
+            return doc.GetValues(fieldName); // according to Document class javadoc, this never returns null
+        }
+
+        protected String MakeFragment(StringBuilder buffer, int[] index, String[] values, WeightedFragInfo fragInfo)
+        {
+            StringBuilder fragment = new StringBuilder();
+            int s = fragInfo.startOffset;
+            String src = GetFragmentSource(buffer, index, values, s, fragInfo.endOffset);
+            int srcIndex = 0;
+            foreach (SubInfo subInfo in fragInfo.subInfos)
+            {
+                foreach (Toffs to in subInfo.termsOffsets)
+                {
+                    fragment.Append(src.Substring(srcIndex, to.startOffset - s - srcIndex)).Append(GetPreTag(subInfo.seqnum))
+                      .Append(src.Substring(to.startOffset - s, to.endOffset - s - (to.startOffset - s))).Append(GetPostTag(subInfo.seqnum));
+                    srcIndex = to.endOffset - s;
+                }
+            }
+            fragment.Append(src.Substring(srcIndex));
+            return fragment.ToString();
+        }
+
+        protected String GetFragmentSource(StringBuilder buffer, int[] index, String[] values, int startOffset, int endOffset)
+        {
+            while (buffer.Length < endOffset && index[0] < values.Length)
+            {
+                if (index[0] > 0 && values[index[0]].Length > 0)
+                    buffer.Append(' ');
+                buffer.Append(values[index[0]++]);
+            }
+            int eo = buffer.Length < endOffset ? buffer.Length : endOffset;
+            return buffer.ToString().Substring(startOffset, eo - startOffset);
+        }
+
+        protected String GetPreTag(int num)
+        {
+            return preTags.Length > num ? preTags[num] : preTags[0];
+        }
+
+        protected String GetPostTag(int num)
+        {
+            return postTags.Length > num ? postTags[num] : postTags[0];
+        }
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj Thu Feb 25 16:32:11 2010
@@ -0,0 +1,108 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{9D2E3153-076F-49C5-B83D-FB2573536B5F}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Lucene.Net.Search.Vectorhighlight</RootNamespace>
+    <AssemblyName>FastVectorHighlighter.Net</AssemblyName>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>2.0</OldToolsVersion>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Lucene.Net, Version=2.9.2.1, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\src\Lucene.Net\bin\Release\Lucene.Net.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BaseFragmentsBuilder.cs" />
+    <Compile Include="FastVectorHighlighter.cs" />
+    <Compile Include="FieldFragList.cs" />
+    <Compile Include="FieldPhraseList.cs" />
+    <Compile Include="FieldQuery.cs" />
+    <Compile Include="FieldTermStack.cs" />
+    <Compile Include="FragListBuilder.cs" />
+    <Compile Include="FragmentsBuilder.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ScoreOrderFragmentsBuilder.cs" />
+    <Compile Include="SimpleFragListBuilder.cs" />
+    <Compile Include="SimpleFragmentsBuilder.cs" />
+    <Compile Include="Support.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="package.html" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj.user
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj.user?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj.user (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.Net.csproj.user Thu Feb 25 16:32:11 2010
@@ -0,0 +1,16 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <PublishUrlHistory>
+    </PublishUrlHistory>
+    <InstallUrlHistory>
+    </InstallUrlHistory>
+    <SupportUrlHistory>
+    </SupportUrlHistory>
+    <UpdateUrlHistory>
+    </UpdateUrlHistory>
+    <BootstrapperUrlHistory>
+    </BootstrapperUrlHistory>
+    <FallbackCulture>en-US</FallbackCulture>
+    <VerifyUploadedFiles>false</VerifyUploadedFiles>
+  </PropertyGroup>
+</Project>
\ No newline at end of file

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FastVectorHighlighter.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,138 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Lucene.Net.Index;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    public class FastVectorHighlighter
+    {
+
+        public static bool DEFAULT_PHRASE_HIGHLIGHT = true;
+        public static bool DEFAULT_FIELD_MATCH = true;
+        private bool phraseHighlight;
+        private bool fieldMatch;
+        private FragListBuilder fragListBuilder;
+        private FragmentsBuilder fragmentsBuilder;
+
+        /// <summary>
+        /// the default constructor.
+        /// </summary>
+        public FastVectorHighlighter():this(DEFAULT_PHRASE_HIGHLIGHT, DEFAULT_FIELD_MATCH)
+        {
+        }
+        
+        /// <summary>
+        /// a constructor. Using SimpleFragListBuilder and ScoreOrderFragmentsBuilder. 
+        /// </summary>
+        /// <param name="phraseHighlight">true or false for phrase highlighting</param>
+        /// <param name="fieldMatch">true of false for field matching</param>
+        public FastVectorHighlighter(bool phraseHighlight, bool fieldMatch):this(phraseHighlight, fieldMatch, new SimpleFragListBuilder(), new ScoreOrderFragmentsBuilder())
+        {
+        }
+            
+        /// <summary>
+        /// a constructor. A FragListBuilder and a FragmentsBuilder can be specified (plugins).
+        /// </summary>
+        /// <param name="phraseHighlight">true of false for phrase highlighting</param>
+        /// <param name="fieldMatch">true of false for field matching</param>
+        /// <param name="fragListBuilder">an instance of FragListBuilder</param>
+        /// <param name="fragmentsBuilder">an instance of FragmentsBuilder</param>
+        public FastVectorHighlighter(bool phraseHighlight, bool fieldMatch,
+            FragListBuilder fragListBuilder, FragmentsBuilder fragmentsBuilder)
+        {
+            this.phraseHighlight = phraseHighlight;
+            this.fieldMatch = fieldMatch;
+            this.fragListBuilder = fragListBuilder;
+            this.fragmentsBuilder = fragmentsBuilder;
+        }
+                
+        /// <summary>
+        /// create a FieldQuery object. 
+        /// </summary>
+        /// <param name="query">a query</param>
+        /// <returns>the created FieldQuery object</returns>
+        public FieldQuery GetFieldQuery(Query query)
+        {
+            return new FieldQuery(query, phraseHighlight, fieldMatch);
+        }
+
+        
+        /// <summary>
+        /// return the best fragment.
+        /// </summary>
+        /// <param name="fieldQuery">FieldQuery object</param>
+        /// <param name="reader">IndexReader of the index</param>
+        /// <param name="docId">document id to be highlighted</param>
+        /// <param name="fieldName">field of the document to be highlighted</param>
+        /// <param name="fragCharSize">the length (number of chars) of a fragment</param>
+        /// <returns>the best fragment (snippet) string</returns>
+        public String GetBestFragment(FieldQuery fieldQuery, IndexReader reader, int docId,
+            String fieldName, int fragCharSize)
+        {
+            FieldFragList fieldFragList = GetFieldFragList(fieldQuery, reader, docId, fieldName, fragCharSize);
+            return fragmentsBuilder.CreateFragment(reader, docId, fieldName, fieldFragList);
+        }
+                
+        /// <summary>
+        /// return the best fragments.
+        /// </summary>
+        /// <param name="fieldQuery">FieldQuery object</param>
+        /// <param name="reader">IndexReader of the index</param>
+        /// <param name="docId">document id to be highlighted</param>
+        /// <param name="fieldName">field of the document to be highlighted</param>
+        /// <param name="fragCharSize">the length (number of chars) of a fragment</param>
+        /// <param name="maxNumFragments">maximum number of fragments</param>
+        /// <returns>created fragments or null when no fragments created. Size of the array can be less than maxNumFragments</returns>
+        public String[] GetBestFragments(FieldQuery fieldQuery, IndexReader reader, int docId,
+            String fieldName, int fragCharSize, int maxNumFragments)
+        {
+            FieldFragList fieldFragList = GetFieldFragList(fieldQuery, reader, docId, fieldName, fragCharSize);
+            return fragmentsBuilder.CreateFragments(reader, docId, fieldName, fieldFragList, maxNumFragments);
+        }
+
+        private FieldFragList GetFieldFragList(FieldQuery fieldQuery, IndexReader reader, int docId,
+            String fieldName, int fragCharSize)
+        {
+            FieldTermStack fieldTermStack = new FieldTermStack(reader, docId, fieldName, fieldQuery);
+            FieldPhraseList fieldPhraseList = new FieldPhraseList(fieldTermStack, fieldQuery);
+            return fragListBuilder.CreateFieldFragList(fieldPhraseList, fragCharSize);
+        }
+
+        /// <summary>
+        /// return whether phraseHighlight or not.
+        /// </summary>
+        /// <returns>return whether phraseHighlight or not.</returns>
+        public bool IsPhraseHighlight() 
+        { 
+            return phraseHighlight; 
+        }
+
+        /// <summary>
+        /// return whether fieldMatch or not.
+        /// </summary>
+        /// <returns>return whether fieldMatch or not.</returns>
+        public bool IsFieldMatch() 
+        { 
+            return fieldMatch; 
+        }
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldFragList.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldFragList.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldFragList.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldFragList.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,118 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Lucene.Net.Documents;
+using Lucene.Net.Search;
+using Lucene.Net.Index;
+
+using Toffs = Lucene.Net.Search.Vectorhighlight.FieldPhraseList.WeightedPhraseInfo.Toffs;
+using WeightedPhraseInfo = Lucene.Net.Search.Vectorhighlight.FieldPhraseList.WeightedPhraseInfo;
+
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    ///<summary>
+    /// FieldFragList has a list of "frag info" that is used by FragmentsBuilder class
+    /// to create fragments (snippets).
+    ///</summary>
+    public class FieldFragList
+    {
+        private int fragCharSize;
+        public List<WeightedFragInfo> fragInfos = new List<WeightedFragInfo>();
+
+        
+        /// <summary>
+        /// a constructor.
+        /// </summary>
+        /// <param name="fragCharSize">the length (number of chars) of a fragment</param>
+        public FieldFragList(int fragCharSize)
+        {
+            this.fragCharSize = fragCharSize;
+        }
+                
+        /// <summary>
+        /// convert the list of WeightedPhraseInfo to WeightedFragInfo, then add it to the fragInfos 
+        /// </summary>
+        /// <param name="startOffset">start offset of the fragment</param>
+        /// <param name="endOffset">end offset of the fragment</param>
+        /// <param name="phraseInfoList">list of WeightedPhraseInfo objects</param>
+        public void Add(int startOffset, int endOffset, List<WeightedPhraseInfo> phraseInfoList)
+        {
+            fragInfos.Add(new WeightedFragInfo(startOffset, endOffset, phraseInfoList));
+        }
+
+        public class WeightedFragInfo
+        {
+
+            internal List<SubInfo> subInfos;
+            internal float totalBoost;
+            internal int startOffset;
+            internal int endOffset;
+
+            public WeightedFragInfo(int startOffset, int endOffset, List<WeightedPhraseInfo> phraseInfoList)
+            {
+                this.startOffset = startOffset;
+                this.endOffset = endOffset;
+                subInfos = new List<SubInfo>();
+                foreach (WeightedPhraseInfo phraseInfo in phraseInfoList)
+                {
+                    SubInfo subInfo = new SubInfo(phraseInfo.text, phraseInfo.termsOffsets, phraseInfo.seqnum);
+                    subInfos.Add(subInfo);
+                    totalBoost += phraseInfo.boost;
+                }
+            }
+
+            public override string ToString()
+            {
+                StringBuilder sb = new StringBuilder();
+                sb.Append("subInfos=(");
+                foreach (SubInfo si in subInfos)
+                    sb.Append(si.ToString());
+                sb.Append(")/").Append(totalBoost.ToString(".0").Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator,".")).Append('(').Append(startOffset).Append(',').Append(endOffset).Append(')');
+                return sb.ToString();
+            }
+
+            internal class SubInfo
+            {
+                internal String text;  // unnecessary member, just exists for debugging purpose
+                internal List<Toffs> termsOffsets;   // usually termsOffsets.size() == 1,
+                // but if position-gap > 1 and slop > 0 then size() could be greater than 1
+                internal int seqnum;
+                internal SubInfo(String text, List<Toffs> termsOffsets, int seqnum)
+                {
+                    this.text = text;
+                    this.termsOffsets = termsOffsets;
+                    this.seqnum = seqnum;
+                }
+
+                public override string ToString()
+                {
+                    StringBuilder sb = new StringBuilder();
+                    sb.Append(text).Append('(');
+                    foreach (Toffs to in termsOffsets)
+                        sb.Append(to.ToString());
+                    sb.Append(')');
+                    return sb.ToString();
+                }
+            }
+        }
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldPhraseList.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldPhraseList.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldPhraseList.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldPhraseList.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,222 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Lucene.Net.Documents;
+using Lucene.Net.Search;
+using Lucene.Net.Index;
+
+using TermInfo = Lucene.Net.Search.Vectorhighlight.FieldTermStack.TermInfo;
+using QueryPhraseMap = Lucene.Net.Search.Vectorhighlight.FieldQuery.QueryPhraseMap;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    /// <summary>
+    /// FieldPhraseList has a list of WeightedPhraseInfo that is used by FragListBuilder
+    /// to create a FieldFragList object.
+    /// </summary>
+    public class FieldPhraseList
+    {
+        public LinkedList<WeightedPhraseInfo> phraseList = new LinkedList<WeightedPhraseInfo>();
+        
+        /// <summary>
+        /// a constructor. 
+        /// </summary>
+        /// <param name="fieldTermStack">FieldTermStack object</param>
+        /// <param name="fieldQuery">FieldQuery object</param>
+        public FieldPhraseList(FieldTermStack fieldTermStack, FieldQuery fieldQuery)
+        {
+            String field = fieldTermStack.GetFieldName();
+
+            LinkedList<TermInfo> phraseCandidate = new LinkedList<TermInfo>();
+            QueryPhraseMap currMap = null;
+            QueryPhraseMap nextMap = null;
+            while (!fieldTermStack.IsEmpty())
+            {
+
+                phraseCandidate.Clear();
+
+                TermInfo ti = fieldTermStack.Pop();
+                currMap = fieldQuery.GetFieldTermMap(field, ti.GetText());
+
+                // if not found, discard top TermInfo from stack, then try next element
+                if (currMap == null) continue;
+
+                // if found, search the longest phrase
+                phraseCandidate.AddLast(ti);
+                while (true)
+                {
+                    ti = fieldTermStack.Pop();
+                    nextMap = null;
+                    if (ti != null)
+                        nextMap = currMap.GetTermMap(ti.GetText());
+                    if (ti == null || nextMap == null)
+                    {
+                        if (ti != null)
+                            fieldTermStack.Push(ti);
+                        if (currMap.IsValidTermOrPhrase(new List<TermInfo>(phraseCandidate)))
+                        {
+                            AddIfNoOverlap(new WeightedPhraseInfo(phraseCandidate, currMap.GetBoost(), currMap.GetTermOrPhraseNumber()));
+                        }
+                        else
+                        {
+                            while (phraseCandidate.Count > 1)
+                            {
+                                TermInfo last = phraseCandidate.Last.Value;
+                                phraseCandidate.RemoveLast();
+                                fieldTermStack.Push(last);
+                                currMap = fieldQuery.SearchPhrase(field, new List<TermInfo>(phraseCandidate));
+                                if (currMap != null)
+                                {
+                                    AddIfNoOverlap(new WeightedPhraseInfo(phraseCandidate, currMap.GetBoost(), currMap.GetTermOrPhraseNumber()));
+                                    break;
+                                }
+                            }
+                        }
+                        break;
+                    }
+                    else
+                    {
+                        phraseCandidate.AddLast(ti);
+                        currMap = nextMap;
+                    }
+                }
+            }
+        }
+
+        void AddIfNoOverlap(WeightedPhraseInfo wpi)
+        {
+            foreach (WeightedPhraseInfo existWpi in phraseList)
+            {
+                if (existWpi.IsOffsetOverlap(wpi)) return;
+            }
+            phraseList.AddLast(wpi);
+        }
+
+        public class WeightedPhraseInfo
+        {
+
+            internal String text;  // unnecessary member, just exists for debugging purpose
+            internal List<Toffs> termsOffsets;   // usually termsOffsets.size() == 1,
+            // but if position-gap > 1 and slop > 0 then size() could be greater than 1
+            internal float boost;  // query boost
+            internal int seqnum;
+
+            public WeightedPhraseInfo(LinkedList<TermInfo> terms, float boost):  this(terms, boost, 0)
+            {
+            }
+
+            public WeightedPhraseInfo(LinkedList<TermInfo> terms, float boost, int number)
+            {
+                this.boost = boost;
+                this.seqnum = number;
+                termsOffsets = new List<Toffs>(terms.Count);
+                TermInfo ti = terms.First.Value;
+                termsOffsets.Add(new Toffs(ti.GetStartOffset(), ti.GetEndOffset()));
+                if (terms.Count == 1)
+                {
+                    text = ti.GetText();
+                    return;
+                }
+                StringBuilder sb = new StringBuilder();
+                sb.Append(ti.GetText());
+                int pos = ti.GetPosition();
+
+                bool dummy = true;
+                foreach(TermInfo ti2 in terms)
+                //for (int i = 1; i < terms.Count; i++)
+                {
+                    if (dummy) { dummy = false; continue; } //Skip First Item {{DIGY}}
+                    ti = ti2;
+                    //ti = terms.get(i);
+                    sb.Append(ti.GetText());
+                    if (ti.GetPosition() - pos == 1)
+                    {
+                        Toffs to = termsOffsets[termsOffsets.Count - 1];
+                        to.SetEndOffset(ti.GetEndOffset());
+                    }
+                    else
+                    {
+                        termsOffsets.Add(new Toffs(ti.GetStartOffset(), ti.GetEndOffset()));
+                    }
+                    pos = ti.GetPosition();
+                }
+                text = sb.ToString();
+            }
+
+            public int GetStartOffset()
+            {
+                return termsOffsets[0].startOffset;
+            }
+
+            public int GetEndOffset()
+            {
+                return termsOffsets[termsOffsets.Count - 1].endOffset;
+            }
+
+            public bool IsOffsetOverlap(WeightedPhraseInfo other)
+            {
+                int so = GetStartOffset();
+                int eo = GetEndOffset();
+                int oso = other.GetStartOffset();
+                int oeo = other.GetEndOffset();
+                if (so <= oso && oso < eo) return true;
+                if (so < oeo && oeo <= eo) return true;
+                if (oso <= so && so < oeo) return true;
+                if (oso < eo && eo <= oeo) return true;
+                return false;
+            }
+
+            public override string ToString()
+            {
+                StringBuilder sb = new StringBuilder();
+                
+                sb.Append(text).Append('(').Append(boost.ToString(".0").Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator,".")).Append(")(");
+                foreach (Toffs to in termsOffsets)
+                {
+                    sb.Append(to);
+                }
+                sb.Append(')');
+                return sb.ToString();
+            }
+
+            public class Toffs
+            {
+                internal int startOffset;
+                internal int endOffset;
+                public Toffs(int startOffset, int endOffset)
+                {
+                    this.startOffset = startOffset;
+                    this.endOffset = endOffset;
+                }
+                internal void SetEndOffset(int endOffset)
+                {
+                    this.endOffset = endOffset;
+                }
+                public override string ToString()
+                {
+                    StringBuilder sb = new StringBuilder();
+                    sb.Append('(').Append(startOffset).Append(',').Append(endOffset).Append(')');
+                    return sb.ToString();
+                }
+            }
+        }
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldQuery.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldQuery.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldQuery.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldQuery.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,441 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Lucene.Net.Search;
+using Lucene.Net.Index;
+
+using TermInfo = Lucene.Net.Search.Vectorhighlight.FieldTermStack.TermInfo;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    public class FieldQuery
+    {
+        bool fieldMatch;
+
+        // fieldMatch==true,  Map<fieldName,QueryPhraseMap>
+        // fieldMatch==false, Map<null,QueryPhraseMap>
+        public HashMap<String, QueryPhraseMap> rootMaps = new HashMap<String, QueryPhraseMap>();
+
+        // fieldMatch==true,  Map<fieldName,setOfTermsInQueries>
+        // fieldMatch==false, Map<null,setOfTermsInQueries>
+        public HashMap<String, List<String>> termSetMap = new HashMap<String, List<String>>();
+
+        int termOrPhraseNumber; // used for colored tag support
+
+        public FieldQuery(Query query, bool phraseHighlight, bool fieldMatch)
+        {
+            this.fieldMatch = fieldMatch;
+            Dictionary<Query, Query> flatQueries = new Dictionary<Query, Query>();
+            flatten(query, flatQueries);
+            SaveTerms(flatQueries);
+            Dictionary<Query, Query> expandQueries = expand(flatQueries);
+
+            foreach (Query flatQuery in expandQueries.Keys)
+            {
+                QueryPhraseMap rootMap = getRootMap(flatQuery);
+                rootMap.Add(flatQuery);
+                if (!phraseHighlight && flatQuery is PhraseQuery)
+                {
+                    PhraseQuery pq = (PhraseQuery)flatQuery;
+                    if (pq.GetTerms().Length > 1)
+                    {
+                        foreach (Term term in pq.GetTerms())
+                            rootMap.AddTerm(term, flatQuery.GetBoost());
+                    }
+                }
+            }
+        }
+
+        public void flatten(Query sourceQuery, Dictionary<Query,Query> flatQueries)
+        {
+            if (sourceQuery is BooleanQuery)
+            {
+                BooleanQuery bq = (BooleanQuery)sourceQuery;
+                foreach (BooleanClause clause in bq.GetClauses())
+                {
+                    if (!clause.IsProhibited())
+                        flatten(clause.GetQuery(), flatQueries);
+                }
+            }
+            else if (sourceQuery is TermQuery)
+            {
+                if (!flatQueries.ContainsKey(sourceQuery))
+                    flatQueries.Add(sourceQuery,sourceQuery);
+            }
+            else if (sourceQuery is PhraseQuery)
+            {
+                if (!flatQueries.ContainsKey(sourceQuery))
+                {
+                    PhraseQuery pq = (PhraseQuery)sourceQuery;
+                    if (pq.GetTerms().Length > 1)
+                        flatQueries.Add(pq,pq);
+                    else if (pq.GetTerms().Length == 1)
+                    {
+                        Query q = new TermQuery(pq.GetTerms()[0]);
+                        flatQueries.Add(q,q);
+                    }
+                }
+            }
+            // else discard queries
+        }
+
+        /*
+         * Create expandQueries from flatQueries.
+         * 
+         * expandQueries := flatQueries + overlapped phrase queries
+         * 
+         * ex1) flatQueries={a,b,c}
+         *      => expandQueries={a,b,c}
+         * ex2) flatQueries={a,"b c","c d"}
+         *      => expandQueries={a,"b c","c d","b c d"}
+         */
+        public Dictionary<Query, Query> expand(Dictionary<Query,Query> flatQueries)
+        {
+            Dictionary<Query, Query> expandQueries = new Dictionary<Query, Query>();
+            foreach(Query query in new Dictionary<Query,Query>(flatQueries).Keys)
+            {
+                //Query query = i.next();
+                flatQueries.Remove(query);
+                expandQueries.Add(query,query);
+                if (!(query is PhraseQuery)) continue;
+                foreach(Query qj in flatQueries.Keys)
+                {
+                    if (!(qj is PhraseQuery)) continue;
+                    CheckOverlap(expandQueries, (PhraseQuery)query, (PhraseQuery)qj);
+                }
+            }
+            return expandQueries;
+        }
+
+        /*
+         * Check if PhraseQuery A and B have overlapped part.
+         * 
+         * ex1) A="a b", B="b c" => overlap; expandQueries={"a b c"}
+         * ex2) A="b c", B="a b" => overlap; expandQueries={"a b c"}
+         * ex3) A="a b", B="c d" => no overlap; expandQueries={}
+         */
+        private void CheckOverlap(Dictionary<Query,Query> expandQueries, PhraseQuery a, PhraseQuery b)
+        {
+            if (a.GetSlop() != b.GetSlop()) return;
+            Term[] ats = a.GetTerms();
+            Term[] bts = b.GetTerms();
+            if (fieldMatch && !ats[0].Field().Equals(bts[0].Field())) return;
+            CheckOverlap(expandQueries, ats, bts, a.GetSlop(), a.GetBoost());
+            CheckOverlap(expandQueries, bts, ats, b.GetSlop(), b.GetBoost());
+        }
+
+        /*
+         * Check if src and dest have overlapped part and if it is, create PhraseQueries and add expandQueries.
+         * 
+         * ex1) src="a b", dest="c d"       => no overlap
+         * ex2) src="a b", dest="a b c"     => no overlap
+         * ex3) src="a b", dest="b c"       => overlap; expandQueries={"a b c"}
+         * ex4) src="a b c", dest="b c d"   => overlap; expandQueries={"a b c d"}
+         * ex5) src="a b c", dest="b c"     => no overlap
+         * ex6) src="a b c", dest="b"       => no overlap
+         * ex7) src="a a a a", dest="a a a" => overlap;
+         *                                     expandQueries={"a a a a a","a a a a a a"}
+         * ex8) src="a b c d", dest="b c"   => no overlap
+         */
+        private void CheckOverlap(Dictionary<Query,Query> expandQueries, Term[] src, Term[] dest, int slop, float boost)
+        {
+            // beginning from 1 (not 0) is safe because that the PhraseQuery has multiple terms
+            // is guaranteed in flatten() method (if PhraseQuery has only one term, flatten()
+            // converts PhraseQuery to TermQuery)
+            for (int i = 1; i < src.Length; i++)
+            {
+                bool overlap = true;
+                for (int j = i; j < src.Length; j++)
+                {
+                    if ((j - i) < dest.Length && !src[j].Text().Equals(dest[j - i].Text()))
+                    {
+                        overlap = false;
+                        break;
+                    }
+                }
+                if (overlap && src.Length - i < dest.Length)
+                {
+                    PhraseQuery pq = new PhraseQuery();
+                    foreach (Term srcTerm in src)
+                        pq.Add(srcTerm);
+                    for (int k = src.Length - i; k < dest.Length; k++)
+                    {
+                        pq.Add(new Term(src[0].Field(), dest[k].Text()));
+                    }
+                    pq.SetSlop(slop);
+                    pq.SetBoost(boost);
+                    if (!expandQueries.ContainsKey(pq))
+                        expandQueries.Add(pq,pq);
+                }
+            }
+        }
+
+        public QueryPhraseMap getRootMap(Query query)
+        {
+            String key = GetKey(query);
+            QueryPhraseMap map=rootMaps.Get(key);
+            if (map == null)
+            {
+                map = new QueryPhraseMap(this);
+                rootMaps.Put(key,map);
+            }
+            return map;
+        }
+
+        /*
+         * Return 'key' string. 'key' is the field name of the Query.
+         * If not fieldMatch, 'key' will be null.
+         */
+        private String GetKey(Query query)
+        {
+            if (!fieldMatch) return null;
+            if (query is TermQuery)
+                return ((TermQuery)query).GetTerm().Field();
+            else if (query is PhraseQuery)
+            {
+                PhraseQuery pq = (PhraseQuery)query;
+                Term[] terms = pq.GetTerms();
+                return terms[0].Field();
+            }
+            else
+                throw new System.ApplicationException("query \"" + query.ToString() + "\" must be flatten first.");
+        }
+
+        /*
+         * Save the set of terms in the queries to termSetMap.
+         * 
+         * ex1) q=name:john
+         *      - fieldMatch==true
+         *          termSetMap=Map<"name",Set<"john">>
+         *      - fieldMatch==false
+         *          termSetMap=Map<null,Set<"john">>
+         *          
+         * ex2) q=name:john title:manager
+         *      - fieldMatch==true
+         *          termSetMap=Map<"name",Set<"john">,
+         *                         "title",Set<"manager">>
+         *      - fieldMatch==false
+         *          termSetMap=Map<null,Set<"john","manager">>
+         *          
+         * ex3) q=name:"john lennon"
+         *      - fieldMatch==true
+         *          termSetMap=Map<"name",Set<"john","lennon">>
+         *      - fieldMatch==false
+         *          termSetMap=Map<null,Set<"john","lennon">>
+         */
+        void SaveTerms(Dictionary<Query,Query> flatQueries)
+        {
+            foreach (Query query in flatQueries.Keys)
+            {
+                List<String> termSet = GetTermSet(query);
+                if (query is TermQuery)
+                    termSet.Add(((TermQuery)query).GetTerm().Text());
+                else if (query is PhraseQuery)
+                {
+                    foreach (Term term in ((PhraseQuery)query).GetTerms())
+                        termSet.Add(term.Text());
+                }
+                else
+                    throw new System.ApplicationException("query \"" + query.ToString() + "\" must be flatten first.");
+            }
+        }
+
+        private List<String> GetTermSet(Query query)
+        {
+            String key = GetKey(query);
+            List<String> set = termSetMap.Get(key);
+            if (set == null)
+            {
+                set = new List<String>();
+                termSetMap.Put(key,set);
+            }
+            return set;
+        }
+
+        public List<String> getTermSet(String field)
+        {
+            if (!fieldMatch) return null;
+            return termSetMap.Get(field);
+        }
+
+        /**
+         * 
+         * @param fieldName
+         * @param term
+         * @return QueryPhraseMap
+         */
+        public QueryPhraseMap GetFieldTermMap(String fieldName, String term)
+        {
+            QueryPhraseMap rootMap = GetRootMap(fieldName);
+            return rootMap == null ? null : rootMap.subMap.Get(term);
+        }
+
+        /**
+         * 
+         * @param fieldName
+         * @param phraseCandidate
+         * @return QueryPhraseMap
+         */
+        public QueryPhraseMap SearchPhrase(String fieldName, List<TermInfo> phraseCandidate)
+        {
+            QueryPhraseMap root = GetRootMap(fieldName);
+            if (root == null) return null;
+            return root.SearchPhrase(phraseCandidate);
+        }
+
+        private QueryPhraseMap GetRootMap(String fieldName)
+        {
+            if (!fieldMatch) return null;
+            return rootMaps.Get(fieldName);
+        }
+
+        int NextTermOrPhraseNumber()
+        {
+            return termOrPhraseNumber++;
+        }
+
+        public class QueryPhraseMap
+        {
+
+            public bool terminal;
+            int slop;   // valid if terminal == true and phraseHighlight == true
+            public float boost;  // valid if terminal == true
+            int termOrPhraseNumber;   // valid if terminal == true
+            FieldQuery fieldQuery;
+            public HashMap<String, QueryPhraseMap> subMap = new HashMap<String, QueryPhraseMap>();
+
+            public QueryPhraseMap(FieldQuery fieldQuery)
+            {
+                this.fieldQuery = fieldQuery;
+            }
+
+            public void AddTerm(Term term, float boost)
+            {
+                QueryPhraseMap map = GetOrNewMap(subMap, term.Text());
+                map.MarkTerminal(boost);
+            }
+
+            private QueryPhraseMap GetOrNewMap(HashMap<String, QueryPhraseMap> subMap, String term)
+            {
+                QueryPhraseMap map = subMap.Get(term);
+                if (map == null)
+                {
+                    map = new QueryPhraseMap(fieldQuery);
+                    subMap.Put(term,map);
+                }
+                return map;
+            }
+
+            public void Add(Query query)
+            {
+                if (query is TermQuery)
+                {
+                    AddTerm(((TermQuery)query).GetTerm(), query.GetBoost());
+                }
+                else if (query is PhraseQuery)
+                {
+                    PhraseQuery pq = (PhraseQuery)query;
+                    Term[] terms = pq.GetTerms();
+                    HashMap<String, QueryPhraseMap> map = subMap;
+                    QueryPhraseMap qpm = null;
+                    foreach (Term term in terms)
+                    {
+                        qpm = GetOrNewMap(map, term.Text());
+                        map = qpm.subMap;
+                    }
+                    qpm.MarkTerminal(pq.GetSlop(), pq.GetBoost());
+                }
+                else
+                    throw new ApplicationException("query \"" + query.ToString() + "\" must be flatten first.");
+            }
+
+            public QueryPhraseMap GetTermMap(String term)
+            {
+                return subMap.Get(term);
+            }
+
+            private void MarkTerminal(float boost)
+            {
+                MarkTerminal(0, boost);
+            }
+
+            private void MarkTerminal(int slop, float boost)
+            {
+                this.terminal = true;
+                this.slop = slop;
+                this.boost = boost;
+                this.termOrPhraseNumber = fieldQuery.NextTermOrPhraseNumber();
+            }
+
+            public bool IsTerminal()
+            {
+                return terminal;
+            }
+
+            public int GetSlop()
+            {
+                return slop;
+            }
+
+            public float GetBoost()
+            {
+                return boost;
+            }
+
+            public int GetTermOrPhraseNumber()
+            {
+                return termOrPhraseNumber;
+            }
+
+            public QueryPhraseMap SearchPhrase(List<TermInfo> phraseCandidate)
+            {
+                QueryPhraseMap currMap = this;
+                foreach (TermInfo ti in phraseCandidate)
+                {
+                    currMap = currMap.subMap[ti.GetText()];
+                    if (currMap == null) return null;
+                }
+                return currMap.IsValidTermOrPhrase(phraseCandidate) ? currMap : null;
+            }
+
+            public bool IsValidTermOrPhrase(List<TermInfo> phraseCandidate)
+            {
+                // check terminal
+                if (!terminal) return false;
+
+                // if the candidate is a term, it is valid
+                if (phraseCandidate.Count == 1) return true;
+
+                // else check whether the candidate is valid phrase
+                // compare position-gaps between terms to slop
+
+                int pos = phraseCandidate[0].GetPosition();
+                for (int i = 1; i < phraseCandidate.Count; i++)
+                {
+                    int nextPos = phraseCandidate[i].GetPosition();
+                    if (Math.Abs(nextPos - pos - 1) > slop) return false;
+                    pos = nextPos;
+                }
+                return true;
+            }
+        }
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldTermStack.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldTermStack.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldTermStack.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FieldTermStack.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,196 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Lucene.Net.Analysis;
+using Lucene.Net.Documents;
+using Lucene.Net.Search;
+using Lucene.Net.Index;
+using Lucene.Net.QueryParsers;
+using Lucene.Net.Store;
+
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+   
+   /// <summary>
+   /// <code>FieldTermStack</code> is a stack that keeps query terms in the specified field
+   /// of the document to be highlighted.
+   /// </summary>
+    public class FieldTermStack
+    {
+        private String fieldName;
+        public LinkedList<TermInfo> termList = new LinkedList<TermInfo>();
+
+        public static void Main(String[] args)
+        {
+            Analyzer analyzer = new WhitespaceAnalyzer();
+            QueryParser parser = new QueryParser("f", analyzer);
+            Query query = parser.Parse("a x:b");
+            FieldQuery fieldQuery = new FieldQuery(query, true, false);
+
+            Directory dir = new RAMDirectory();
+            IndexWriter writer = new IndexWriter(dir, analyzer, IndexWriter.MaxFieldLength.LIMITED);
+            Document doc = new Document();
+            doc.Add(new Field("f", "a a a b b c a b b c d e f", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
+            doc.Add(new Field("f", "b a b a f", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
+            writer.AddDocument(doc);
+            writer.Close();
+
+            IndexReader reader = IndexReader.Open(dir,true);
+            FieldTermStack ftl = new FieldTermStack(reader, 0, "f", fieldQuery);
+            reader.Close();
+        }
+                
+        /// <summary>
+        /// a constructor. 
+        /// </summary>
+        /// <param name="reader">IndexReader of the index</param>
+        /// <param name="docId">document id to be highlighted</param>
+        /// <param name="fieldName">field of the document to be highlighted</param>
+        /// <param name="fieldQuery">FieldQuery object</param>
+        public FieldTermStack(IndexReader reader, int docId, String fieldName, FieldQuery fieldQuery)
+        {
+            this.fieldName = fieldName;
+
+            TermFreqVector tfv = reader.GetTermFreqVector(docId, fieldName);
+            if (tfv == null) return; // just return to make null snippets
+            TermPositionVector tpv = null;
+            try
+            {
+                tpv = (TermPositionVector)tfv;
+            }
+            catch (InvalidCastException e)
+            {
+                return; // just return to make null snippets
+            }
+
+            List<String> termSet = fieldQuery.getTermSet(fieldName);
+            // just return to make null snippet if un-matched fieldName specified when fieldMatch == true
+            if (termSet == null) return;
+
+            foreach (String term in tpv.GetTerms())
+            {
+                if (!termSet.Contains(term)) continue;
+                int index = tpv.IndexOf(term);
+                TermVectorOffsetInfo[] tvois = tpv.GetOffsets(index);
+                if (tvois == null) return; // just return to make null snippets
+                int[] poss = tpv.GetTermPositions(index);
+                if (poss == null) return; // just return to make null snippets
+                for (int i = 0; i < tvois.Length; i++)
+                    termList.AddLast(new TermInfo(term, tvois[i].GetStartOffset(), tvois[i].GetEndOffset(), poss[i]));
+            }
+
+            // sort by position
+            //Collections.sort(termList);
+            Sort(termList);
+        }
+
+        void Sort(LinkedList<TermInfo> linkList)
+        {
+            TermInfo[] arr = new TermInfo[linkList.Count];
+            linkList.CopyTo(arr, 0);
+            Array.Sort(arr, new Comparison<TermInfo>(PosComparer));
+
+            linkList.Clear();
+            foreach (TermInfo t in arr) linkList.AddLast(t);
+        }
+
+        int PosComparer(TermInfo t1,TermInfo t2)
+        {
+            return t1.GetPosition() - t2.GetPosition();
+        }
+                
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns>field name</returns>
+        public String GetFieldName()
+        {
+            return fieldName;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns>the top TermInfo object of the stack</returns>
+        public TermInfo Pop()
+        {
+            if (termList.Count == 0) return null;
+
+            LinkedListNode<TermInfo> top =  termList.First;
+            termList.RemoveFirst();
+            return top.Value;
+        }
+                
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="termInfo">the TermInfo object to be put on the top of the stack</param>
+        public void Push(TermInfo termInfo)
+        {
+            // termList.push( termInfo );  // avoid Java 1.6 feature
+            termList.AddFirst(termInfo);
+        }
+
+        /// <summary>
+        /// to know whether the stack is empty 
+        /// </summary>
+        /// <returns>true if the stack is empty, false if not</returns>
+        public bool IsEmpty()
+        {
+            return termList == null || termList.Count == 0;
+        }
+
+        public class TermInfo : IComparable<TermInfo>
+        {
+
+            String text;
+            int startOffset;
+            int endOffset;
+            int position;
+
+            public TermInfo(String text, int startOffset, int endOffset, int position)
+            {
+                this.text = text;
+                this.startOffset = startOffset;
+                this.endOffset = endOffset;
+                this.position = position;
+            }
+
+            public String GetText() { return text; }
+            public int GetStartOffset() { return startOffset; }
+            public int GetEndOffset() { return endOffset; }
+            public int GetPosition() { return position; }
+
+            public override string ToString()
+            {
+                StringBuilder sb = new StringBuilder();
+                sb.Append(text).Append('(').Append(startOffset).Append(',').Append(endOffset).Append(',').Append(position).Append(')');
+                return sb.ToString();
+            }
+
+            public int CompareTo(TermInfo o)
+            {
+                return (this.position - o.position);
+            }
+        }
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragListBuilder.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragListBuilder.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragListBuilder.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragListBuilder.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    /// <summary>
+    /// 
+    /// FragListBuilder is an interface for FieldFragList builder classes.
+    /// A FragListBuilder class can be plugged in to Highlighter.
+     /// </summary>
+    public interface FragListBuilder
+    {
+        /// <summary>
+        /// create a FieldFragList. 
+        /// </summary>
+        /// <param name="fieldPhraseList">FieldPhraseList object</param>
+        /// <param name="fragCharSize">the length (number of chars) of a fragment</param>
+        /// <returns>the created FieldFragList object</returns>
+        FieldFragList CreateFieldFragList(FieldPhraseList fieldPhraseList, int fragCharSize);
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragmentsBuilder.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragmentsBuilder.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragmentsBuilder.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/FragmentsBuilder.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Lucene.Net.Documents;
+using Lucene.Net.Search;
+using Lucene.Net.Index;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    /// <summary>
+    /// FragmentsBuilder is an interface for fragments (snippets) builder classes.
+    /// A FragmentsBuilder class can be plugged in to Highlighter.
+    /// </summary>
+    public interface FragmentsBuilder
+    {
+        /// <summary>
+        /// create a fragment.
+        /// </summary>
+        /// <param name="reader">IndexReader of the index</param>
+        /// <param name="docId">document id to be highlighted</param>
+        /// <param name="fieldName">field of the document to be highlighted</param>
+        /// <param name="fieldFragList">FieldFragList object</param>
+        /// <returns>a created fragment or null when no fragment created</returns>
+        String CreateFragment( IndexReader reader, int docId, String fieldName, FieldFragList fieldFragList ) ;
+
+        
+        /// <summary>
+        /// create multiple fragments.
+        /// </summary>
+        /// <param name="reader">IndexReader of the index</param>
+        /// <param name="docId">document id to be highlighted</param>
+        /// <param name="fieldName">field of the document to be highlighted</param>
+        /// <param name="fieldFragList">ieldFragList object</param>
+        /// <param name="maxNumFragments">maximum number of fragments</param>
+        /// <returns>created fragments or null when no fragments created. Size of the array can be less than maxNumFragments</returns>
+        String[] CreateFragments( IndexReader reader, int docId, String fieldName, FieldFragList fieldFragList, int maxNumFragments ) ;
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Properties/AssemblyInfo.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Properties/AssemblyInfo.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Properties/AssemblyInfo.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Properties/AssemblyInfo.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FastVectorHighlighter.Net for Apache Lucene.Net")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("FastVectorHighlighter.Net")]
+[assembly: AssemblyCopyright("Copyright 2006 - 2010 The Apache Software Foundation")]
+[assembly: AssemblyTrademark("Copyright 2006 - 2010 The Apache Software Foundation")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("502a387b-1b01-4e2a-8754-d4cf9701b70e")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.9.2")]
+[assembly: AssemblyFileVersion("2.9.2")]

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/ScoreOrderFragmentsBuilder.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/ScoreOrderFragmentsBuilder.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/ScoreOrderFragmentsBuilder.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/ScoreOrderFragmentsBuilder.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,76 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using WeightedFragInfo = Lucene.Net.Search.Vectorhighlight.FieldFragList.WeightedFragInfo;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    /**
+ * An implementation of FragmentsBuilder that outputs score-order fragments.
+ */
+    public class ScoreOrderFragmentsBuilder : BaseFragmentsBuilder
+    {
+
+        /// <summary>
+        /// a constructor.
+        /// </summary>
+        public ScoreOrderFragmentsBuilder():base()
+        {
+        }
+
+
+        /// <summary>
+        /// a constructor.
+        /// </summary>
+        /// <param name="preTags">array of pre-tags for markup terms</param>
+        /// <param name="postTags">array of post-tags for markup terms</param>
+        public ScoreOrderFragmentsBuilder(String[] preTags, String[] postTags):  base(preTags, postTags)
+        {
+        }
+
+        /// <summary>
+        /// Sort by score the list of WeightedFragInfo
+        /// </summary>
+        public override List<WeightedFragInfo> GetWeightedFragInfoList(List<WeightedFragInfo> src)
+        {
+            src.Sort(new ScoreComparator());
+            return src;
+        }
+
+        public class ScoreComparator : IComparer<WeightedFragInfo>
+        {  // Comparator<WeightedFragInfo> {
+
+            public int Compare(WeightedFragInfo o1, WeightedFragInfo o2)
+            {
+                if (o1.totalBoost > o2.totalBoost) return -1;
+                else if (o1.totalBoost < o2.totalBoost) return 1;
+                // if same score then check startOffset
+                else
+                {
+                    if (o1.startOffset < o2.startOffset) return -1;
+                    else if (o1.startOffset > o2.startOffset) return 1;
+                }
+                return 0;
+            }
+        }
+    }
+
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragListBuilder.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragListBuilder.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragListBuilder.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragListBuilder.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,92 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using WeightedPhraseInfo = Lucene.Net.Search.Vectorhighlight.FieldPhraseList.WeightedPhraseInfo;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    /// <summary>
+    /// A simple implementation of FragListBuilder.
+    /// </summary>
+    public class SimpleFragListBuilder : FragListBuilder
+    {
+
+        public static int MARGIN = 6;
+        public static int MIN_FRAG_CHAR_SIZE = MARGIN * 3;
+
+        public FieldFragList CreateFieldFragList(FieldPhraseList fieldPhraseList, int fragCharSize)
+        {
+            if (fragCharSize < MIN_FRAG_CHAR_SIZE)
+                throw new ArgumentException("fragCharSize(" + fragCharSize + ") is too small. It must be " +
+                    MIN_FRAG_CHAR_SIZE + " or higher.");
+
+            FieldFragList ffl = new FieldFragList(fragCharSize);
+
+            List<WeightedPhraseInfo> wpil = new List<WeightedPhraseInfo>();
+            LinkedList<WeightedPhraseInfo>.Enumerator ite = fieldPhraseList.phraseList.GetEnumerator();
+
+            WeightedPhraseInfo phraseInfo = null;
+            int startOffset = 0;
+            bool taken = false;
+            while (true)
+            {
+                if (!taken)
+                {
+                    if (!ite.MoveNext()) break;
+                    phraseInfo = ite.Current;
+                }
+                taken = false;
+                if (phraseInfo == null) break;
+
+                // if the phrase violates the border of previous fragment, discard it and try next phrase
+                if (phraseInfo.GetStartOffset() < startOffset) continue;
+
+                wpil.Clear();
+                wpil.Add(phraseInfo);
+                int st = phraseInfo.GetStartOffset() - MARGIN < startOffset ?
+                    startOffset : phraseInfo.GetStartOffset() - MARGIN;
+                int en = st + fragCharSize;
+                if (phraseInfo.GetEndOffset() > en)
+                    en = phraseInfo.GetEndOffset();
+                startOffset = en;
+
+                while (true)
+                {
+                    if (ite.MoveNext())
+                    {
+                        phraseInfo = ite.Current;
+                        taken = true;
+                        if (phraseInfo == null) break;
+                    }
+                    else
+                        break;
+                    if (phraseInfo.GetEndOffset() <= en)
+                        wpil.Add(phraseInfo);
+                    else
+                        break;
+                }
+                ffl.Add(st, en, wpil);
+            }
+            return ffl;
+        }
+
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragmentsBuilder.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragmentsBuilder.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragmentsBuilder.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/SimpleFragmentsBuilder.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using WeightedFragInfo = Lucene.Net.Search.Vectorhighlight.FieldFragList.WeightedFragInfo;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+   
+    /// <summary>
+    /// A simple implementation of FragmentsBuilder.
+    /// </summary>
+    public class SimpleFragmentsBuilder : BaseFragmentsBuilder
+    {
+        /// <summary>
+        /// a constructor.
+        /// </summary>
+        public SimpleFragmentsBuilder() : base()
+        {
+        }
+                
+
+        /// <summary>
+        /// a constructor.
+        /// </summary>
+        /// <param name="preTags">array of pre-tags for markup terms</param>
+        /// <param name="postTags">array of post-tags for markup terms</param>
+        public SimpleFragmentsBuilder(String[] preTags, String[] postTags)
+            : base(preTags, postTags)
+        {
+
+        }
+
+        /// <summary>
+        /// do nothing. return the source list.
+        /// </summary>
+        public override List<WeightedFragInfo> GetWeightedFragInfoList(List<WeightedFragInfo> src)
+        {
+            return src;
+        }
+    }
+}

Added: lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Support.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Support.cs?rev=916340&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Support.cs (added)
+++ lucene/lucene.net/trunk/C#/contrib/FastVectorHighlighter.Net/FastVectorHighlighter.Net/Support.cs Thu Feb 25 16:32:11 2010
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Lucene.Net.Search.Vectorhighlight
+{
+    public class HashMap<K, V> : Dictionary<K, V>
+    {
+        V _NullKeyValue = default(V);
+
+        public new void Add(K key,V value)
+        {
+            if (key == null)
+                _NullKeyValue = value;
+            else
+                base.Add(key,value);
+        }
+
+        public new int Count
+        {
+            get
+            {
+                return base.Count + (_NullKeyValue!= null ? 1 : 0);
+            }
+        }
+
+        public new V this[K key]
+        {
+            get{
+                return Get(key);
+            }
+            set{
+                Add(key,value);
+            }
+        }
+
+        public V Get(K key)
+        {
+            if (key == null) return _NullKeyValue;
+
+            V v = default(V);
+            base.TryGetValue(key, out v);
+            return v;
+        }
+
+        public void Put(K key, V val) 
+        {
+            Add(key,val);
+        }
+    }
+}
+
+namespace System.Runtime.CompilerServices
+{
+    [AttributeUsage(AttributeTargets.Method)]
+    public sealed class ExtensionAttribute : Attribute
+    {
+        public ExtensionAttribute() { }
+    }
+}



Mime
View raw message