lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From synhers...@apache.org
Subject [2/5] lucenenet git commit: Adding Expressions with some failing tests
Date Sat, 31 Jan 2015 20:03:50 GMT
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Lucene.Net.Expressions.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Lucene.Net.Expressions.csproj b/src/Lucene.Net.Expressions/Lucene.Net.Expressions.csproj
new file mode 100644
index 0000000..5b7d06b
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Lucene.Net.Expressions.csproj
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Lucene.Net.Expressions</RootNamespace>
+    <AssemblyName>Lucene.Net.Expressions</AssemblyName>
+    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>0478e2ae</NuGetPackageImportStamp>
+  </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="Antlr3.Runtime">
+      <HintPath>..\..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bindings.cs" />
+    <Compile Include="Expression.cs" />
+    <Compile Include="ExpressionComparator.cs" />
+    <Compile Include="ExpressionFunctionValues.cs" />
+    <Compile Include="ExpressionRescorer.cs" />
+    <Compile Include="ExpressionSortField.cs" />
+    <Compile Include="ExpressionValueSource.cs" />
+    <Compile Include="JS\JavascriptCompiler.cs" />
+    <Compile Include="JS\JavascriptLexer.cs" />
+    <Compile Include="JS\JavascriptParser.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+      <DependentUpon>Settings.settings</DependentUpon>
+    </Compile>
+    <Compile Include="ScoreFunctionValues.cs" />
+    <Compile Include="ScoreValueSource.cs" />
+    <Compile Include="SimpleBindings.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Lucene.Net.Core\Lucene.Net.csproj">
+      <Project>{5D4AD9BE-1FFB-41AB-9943-25737971BF57}</Project>
+      <Name>Lucene.Net</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Lucene.Net.Queries\Lucene.Net.Queries.csproj">
+      <Project>{69D7956C-C2CC-4708-B399-A188FEC384C4}</Project>
+      <Name>Lucene.Net.Queries</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\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

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Properties/AssemblyInfo.cs b/src/Lucene.Net.Expressions/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..306b537
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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("Lucene.Net.Expressions")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Lucene.Net.Expressions")]
+[assembly: AssemblyCopyright("Copyright ©  2014")]
+[assembly: AssemblyTrademark("")]
+[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("6f5d9768-c42b-4dca-881b-001f61618cac")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Properties/Settings.Designer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Properties/Settings.Designer.cs b/src/Lucene.Net.Expressions/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..db95fb0
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Properties/Settings.Designer.cs
@@ -0,0 +1,323 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.0
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Lucene.Net.Expressions.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+        
+        [global::System.Configuration.ApplicationScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Abs, 1")]
+        public string abs {
+            get {
+                return ((string)(this["abs"]));
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Acos, 1")]
+        public string acos {
+            get {
+                return ((string)(this["acos"]));
+            }
+            set {
+                this["acos"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.MathUtil, Acosh, 1")]
+        public string acosh {
+            get {
+                return ((string)(this["acosh"]));
+            }
+            set {
+                this["acosh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Asin, 1")]
+        public string asin {
+            get {
+                return ((string)(this["asin"]));
+            }
+            set {
+                this["asin"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.MathUtil, Asinh, 1")]
+        public string asinh {
+            get {
+                return ((string)(this["asinh"]));
+            }
+            set {
+                this["asinh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Atan, 1")]
+        public string atan {
+            get {
+                return ((string)(this["atan"]));
+            }
+            set {
+                this["atan"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Atan2, 2")]
+        public string atan2 {
+            get {
+                return ((string)(this["atan2"]));
+            }
+            set {
+                this["atan2"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.MathUtil, Atanh, 1")]
+        public string atanh {
+            get {
+                return ((string)(this["atanh"]));
+            }
+            set {
+                this["atanh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Ceiling, 1")]
+        public string ceil {
+            get {
+                return ((string)(this["ceil"]));
+            }
+            set {
+                this["ceil"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Cos, 1")]
+        public string cos {
+            get {
+                return ((string)(this["cos"]));
+            }
+            set {
+                this["cos"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Cosh, 1")]
+        public string cosh {
+            get {
+                return ((string)(this["cosh"]));
+            }
+            set {
+                this["cosh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Exp, 1")]
+        public string exp {
+            get {
+                return ((string)(this["exp"]));
+            }
+            set {
+                this["exp"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Floor, 1")]
+        public string floor {
+            get {
+                return ((string)(this["floor"]));
+            }
+            set {
+                this["floor"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.SloppyMath, Haversin, 4")]
+        public string haversin {
+            get {
+                return ((string)(this["haversin"]));
+            }
+            set {
+                this["haversin"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Log, 1")]
+        public string ln {
+            get {
+                return ((string)(this["ln"]));
+            }
+            set {
+                this["ln"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Log10, 1")]
+        public string log10 {
+            get {
+                return ((string)(this["log10"]));
+            }
+            set {
+                this["log10"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.MathUtil, Log, 2")]
+        public string logn {
+            get {
+                return ((string)(this["logn"]));
+            }
+            set {
+                this["logn"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Max, 2")]
+        public string max {
+            get {
+                return ((string)(this["max"]));
+            }
+            set {
+                this["max"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Min, 2")]
+        public string min {
+            get {
+                return ((string)(this["min"]));
+            }
+            set {
+                this["min"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Pow, 2")]
+        public string pow {
+            get {
+                return ((string)(this["pow"]));
+            }
+            set {
+                this["pow"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Sin, 1")]
+        public string sin {
+            get {
+                return ((string)(this["sin"]));
+            }
+            set {
+                this["sin"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Sinh, 1")]
+        public string sinh {
+            get {
+                return ((string)(this["sinh"]));
+            }
+            set {
+                this["sinh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Sqrt, 1")]
+        public string sqrt {
+            get {
+                return ((string)(this["sqrt"]));
+            }
+            set {
+                this["sqrt"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Tan, 1")]
+        public string tan {
+            get {
+                return ((string)(this["tan"]));
+            }
+            set {
+                this["tan"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Tanh, 1")]
+        public string tanh {
+            get {
+                return ((string)(this["tanh"]));
+            }
+            set {
+                this["tanh"] = value;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Properties/Settings.settings
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Properties/Settings.settings b/src/Lucene.Net.Expressions/Properties/Settings.settings
new file mode 100644
index 0000000..3fd130f
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Properties/Settings.settings
@@ -0,0 +1,81 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Lucene.Net.Expressions.Properties" GeneratedClassName="Settings">
+  <Profiles />
+  <Settings>
+    <Setting Name="abs" Type="System.String" Scope="Application">
+      <Value Profile="(Default)">System.Math, Abs, 1</Value>
+    </Setting>
+    <Setting Name="acos" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Acos, 1</Value>
+    </Setting>
+    <Setting Name="acosh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.MathUtil, Acosh, 1</Value>
+    </Setting>
+    <Setting Name="asin" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Asin, 1</Value>
+    </Setting>
+    <Setting Name="asinh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.MathUtil, Asinh, 1</Value>
+    </Setting>
+    <Setting Name="atan" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Atan, 1</Value>
+    </Setting>
+    <Setting Name="atan2" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Atan2, 2</Value>
+    </Setting>
+    <Setting Name="atanh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.MathUtil, Atanh, 1</Value>
+    </Setting>
+    <Setting Name="ceil" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Ceiling, 1</Value>
+    </Setting>
+    <Setting Name="cos" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Cos, 1</Value>
+    </Setting>
+    <Setting Name="cosh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Cosh, 1</Value>
+    </Setting>
+    <Setting Name="exp" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Exp, 1</Value>
+    </Setting>
+    <Setting Name="floor" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Floor, 1</Value>
+    </Setting>
+    <Setting Name="haversin" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.SloppyMath, Haversin, 4</Value>
+    </Setting>
+    <Setting Name="ln" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Log, 1</Value>
+    </Setting>
+    <Setting Name="log10" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Log10, 1</Value>
+    </Setting>
+    <Setting Name="logn" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.MathUtil, Log, 2</Value>
+    </Setting>
+    <Setting Name="max" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Max, 2</Value>
+    </Setting>
+    <Setting Name="min" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Min, 2</Value>
+    </Setting>
+    <Setting Name="pow" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Pow, 2</Value>
+    </Setting>
+    <Setting Name="sin" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Sin, 1</Value>
+    </Setting>
+    <Setting Name="sinh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Sinh, 1</Value>
+    </Setting>
+    <Setting Name="sqrt" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Sqrt, 1</Value>
+    </Setting>
+    <Setting Name="tan" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Tan, 1</Value>
+    </Setting>
+    <Setting Name="tanh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Tanh, 1</Value>
+    </Setting>
+  </Settings>
+</SettingsFile>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ScoreFunctionValues.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ScoreFunctionValues.cs b/src/Lucene.Net.Expressions/ScoreFunctionValues.cs
new file mode 100644
index 0000000..972d8c7
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ScoreFunctionValues.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Queries.Function.DocValues;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+    /// <summary>
+    /// A utility class to allow expressions to access the score as a
+    /// <see cref="Lucene.Net.Queries.Function.FunctionValues">Lucene.Net.Queries.Function.FunctionValues
+    /// 	</see>
+    /// .
+    /// </summary>
+    internal class ScoreFunctionValues : DoubleDocValues
+    {
+        internal readonly Scorer scorer;
+
+        internal ScoreFunctionValues(ValueSource parent, Scorer scorer)
+            : base(parent)
+        {
+            this.scorer = scorer;
+        }
+
+        public override double DoubleVal(int document)
+        {
+            Debug.Assert(document == scorer.DocID());
+            var score = scorer.Score();
+            Console.WriteLine("Score = {0}",score);
+            return score;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ScoreValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ScoreValueSource.cs b/src/Lucene.Net.Expressions/ScoreValueSource.cs
new file mode 100644
index 0000000..b9f8d45
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ScoreValueSource.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections;
+using Lucene.Net.Index;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>
+	/// A
+	/// <see cref="Lucene.Net.Queries.Function.ValueSource">Lucene.Net.Queries.Function.ValueSource
+	/// 	</see>
+	/// which uses the
+	/// <see cref="Lucene.Net.Search.Scorer">Lucene.Net.Search.Scorer</see>
+	/// passed through
+	/// the context map by
+	/// <see cref="ExpressionComparator">ExpressionComparator</see>
+	/// .
+	/// </summary>
+	internal class ScoreValueSource : ValueSource
+	{
+	    private Scorer hashCodeObj;
+
+	    /// <summary>
+		/// <code>context</code> must contain a key "scorer" which is a
+		/// <see cref="Lucene.Net.Search.Scorer">Lucene.Net.Search.Scorer</see>
+		/// .
+		/// </summary>
+		/// <exception cref="System.IO.IOException"></exception>
+		public override FunctionValues GetValues(IDictionary context, AtomicReaderContext
+			 readerContext)
+		{
+			Scorer v = (Scorer)context["scorer"];
+		    hashCodeObj = v;
+			if (v == null)
+			{
+				throw new InvalidOperationException("Expressions referencing the score can only be used for sorting"
+					);
+			}
+			return new ScoreFunctionValues(this, v);
+		}
+
+		public override bool Equals(object o)
+		{
+			return o == this;
+		}
+
+		public override int GetHashCode()
+		{
+            //TODO: revist this and return something meaningful
+		    return 777;
+		}
+
+		public override string Description
+		{
+		    get { return "score()"; }
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/SimpleBindings.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/SimpleBindings.cs b/src/Lucene.Net.Expressions/SimpleBindings.cs
new file mode 100644
index 0000000..f317970
--- /dev/null
+++ b/src/Lucene.Net.Expressions/SimpleBindings.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Queries.Function.ValueSources;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>
+	/// Simple class that binds expression variable names to
+	/// <see cref="Lucene.Net.Search.SortField">Lucene.Net.Search.SortField
+	/// 	</see>
+	/// s
+	/// or other
+	/// <see cref="Expression">Expression</see>
+	/// s.
+	/// <p>
+	/// Example usage:
+	/// <pre class="prettyprint">
+	/// SimpleBindings bindings = new SimpleBindings();
+	/// // document's text relevance score
+	/// bindings.add(new SortField("_score", SortField.Type.SCORE));
+	/// // integer NumericDocValues field (or from FieldCache)
+	/// bindings.add(new SortField("popularity", SortField.Type.INT));
+	/// // another expression
+	/// bindings.add("recency", myRecencyExpression);
+	/// // create a sort field in reverse order
+	/// Sort sort = new Sort(expr.getSortField(bindings, true));
+	/// </pre>
+	/// </summary>
+	/// <lucene.experimental></lucene.experimental>
+	public sealed class SimpleBindings : Bindings
+	{
+		internal readonly IDictionary<string, object> map = new Dictionary<string, object
+			>();
+
+	    /// <summary>Adds a SortField to the bindings.</summary>
+		/// <remarks>
+		/// Adds a SortField to the bindings.
+		/// <p>
+		/// This can be used to reference a DocValuesField, a field from
+		/// FieldCache, the document's score, etc.
+		/// </remarks>
+		public void Add(SortField sortField)
+		{
+			map[sortField.Field] = sortField;
+		}
+
+		/// <summary>Adds an Expression to the bindings.</summary>
+		/// <remarks>
+		/// Adds an Expression to the bindings.
+		/// <p>
+		/// This can be used to reference expressions from other expressions.
+		/// </remarks>
+		public void Add(string name, Expression expression)
+		{
+			map[name] = expression;
+		}
+
+		public override ValueSource GetValueSource(string name)
+		{
+		    object o = map[name];
+			if (o == null)
+			{
+				throw new ArgumentException("Invalid reference '" + name + "'");
+			}
+		    var expression = o as Expression;
+		    if (expression != null)
+		    {
+		        return expression.GetValueSource(this);
+		    }
+		    SortField field = (SortField)o;
+			switch (field.Type)
+			{
+				case SortField.Type_e.INT:
+				{
+					return new IntFieldSource(field.Field, (FieldCache.IIntParser) field.Parser);
+				}
+
+				case SortField.Type_e.LONG:
+				{
+					return new LongFieldSource(field.Field, (FieldCache.ILongParser)field.Parser);
+				}
+
+				case SortField.Type_e.FLOAT:
+				{
+					return new FloatFieldSource(field.Field, (FieldCache.IFloatParser)field.Parser);
+				}
+
+				case SortField.Type_e.DOUBLE:
+				{
+					return new DoubleFieldSource(field.Field, (FieldCache.IDoubleParser)field.Parser);
+				}
+
+				case SortField.Type_e.SCORE:
+				{
+					return GetScoreValueSource();
+				}
+
+				default:
+				{
+					throw new NotSupportedException();
+				}
+			}
+		}
+
+		/// <summary>Traverses the graph of bindings, checking there are no cycles or missing references
+		/// 	</summary>
+		/// <exception cref="System.ArgumentException">if the bindings is inconsistent</exception>
+		public void Validate()
+		{
+			foreach (object o in map.Values)
+			{
+				if (o is Expression)
+				{
+					Expression expr = (Expression)o;
+					try
+					{
+						expr.GetValueSource(this);
+					}
+					catch (StackOverflowException)
+					{
+						throw new ArgumentException("Recursion Error: Cycle detected originating in (" + 
+							expr.sourceText + ")");
+					}
+				}
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/app.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/app.config b/src/Lucene.Net.Expressions/app.config
new file mode 100644
index 0000000..4dcad5c
--- /dev/null
+++ b/src/Lucene.Net.Expressions/app.config
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <configSections>
+        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="Lucene.Net.Expressions.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+        </sectionGroup>
+        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="Lucene.Net.Expressions.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+        </sectionGroup>
+    </configSections>
+    <applicationSettings>
+        <Lucene.Net.Expressions.Properties.Settings>
+            <setting name="abs" serializeAs="String">
+                <value>System.Math, Abs, 1</value>
+            </setting>
+        </Lucene.Net.Expressions.Properties.Settings>
+    </applicationSettings>
+    <userSettings>
+        <Lucene.Net.Expressions.Properties.Settings>
+            <setting name="acos" serializeAs="String">
+                <value>System.Math, Acos, 1</value>
+            </setting>
+            <setting name="acosh" serializeAs="String">
+                <value>Lucene.Net.Util.MathUtil, Acosh, 1</value>
+            </setting>
+            <setting name="asin" serializeAs="String">
+                <value>System.Math, Asin, 1</value>
+            </setting>
+            <setting name="asinh" serializeAs="String">
+                <value>Lucene.Net.Util.MathUtil, Asinh, 1</value>
+            </setting>
+            <setting name="atan" serializeAs="String">
+                <value>System.Math, Atan, 1</value>
+            </setting>
+            <setting name="atan2" serializeAs="String">
+                <value>System.Math, Atan2, 2</value>
+            </setting>
+            <setting name="atanh" serializeAs="String">
+                <value>Lucene.Net.Util.MathUtil, Atanh, 1</value>
+            </setting>
+            <setting name="ceil" serializeAs="String">
+                <value>System.Math, Ceiling, 1</value>
+            </setting>
+            <setting name="cos" serializeAs="String">
+                <value>System.Math, Cos, 1</value>
+            </setting>
+            <setting name="cosh" serializeAs="String">
+                <value>System.Math, Cosh, 1</value>
+            </setting>
+            <setting name="exp" serializeAs="String">
+                <value>System.Math, Exp, 1</value>
+            </setting>
+            <setting name="floor" serializeAs="String">
+                <value>System.Math, Floor, 1</value>
+            </setting>
+            <setting name="haversin" serializeAs="String">
+                <value>Lucene.Net.Util.SloppyMath, Haversin, 4</value>
+            </setting>
+            <setting name="ln" serializeAs="String">
+                <value>System.Math, Log, 1</value>
+            </setting>
+            <setting name="log10" serializeAs="String">
+                <value>System.Math, Log10, 1</value>
+            </setting>
+            <setting name="logn" serializeAs="String">
+                <value>Lucene.Net.Util.MathUtil, Log, 2</value>
+            </setting>
+            <setting name="max" serializeAs="String">
+                <value>System.Math, Max, 2</value>
+            </setting>
+            <setting name="min" serializeAs="String">
+                <value>System.Math, Min, 2</value>
+            </setting>
+            <setting name="pow" serializeAs="String">
+                <value>System.Math, Pow, 2</value>
+            </setting>
+            <setting name="sin" serializeAs="String">
+                <value>System.Math, Sin, 1</value>
+            </setting>
+            <setting name="sinh" serializeAs="String">
+                <value>System.Math, Sinh, 1</value>
+            </setting>
+            <setting name="sqrt" serializeAs="String">
+                <value>System.Math, Sqrt, 1</value>
+            </setting>
+            <setting name="tan" serializeAs="String">
+                <value>System.Math, Tan, 1</value>
+            </setting>
+            <setting name="tanh" serializeAs="String">
+                <value>System.Math, Tanh, 1</value>
+            </setting>
+        </Lucene.Net.Expressions.Properties.Settings>
+    </userSettings>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/packages.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/packages.config b/src/Lucene.Net.Expressions/packages.config
new file mode 100644
index 0000000..8cc9e63
--- /dev/null
+++ b/src/Lucene.Net.Expressions/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Antlr" version="3.5.0.2" targetFramework="net451" />
+</packages>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/JS/TestCustomFunctions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/JS/TestCustomFunctions.cs b/src/Lucene.Net.Tests.Expressions/JS/TestCustomFunctions.cs
new file mode 100644
index 0000000..22e8f12
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/JS/TestCustomFunctions.cs
@@ -0,0 +1,262 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq.Expressions;
+using System.Reflection;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Support;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions.JS
+{
+	[TestFixture]
+	public class TestCustomFunctions : Util.LuceneTestCase
+	{
+		private static double DELTA = 0.0000001;
+
+		/// <summary>empty list of methods</summary>
+		[Test]
+		public virtual void TestEmpty()
+		{
+			IDictionary<string, MethodInfo> functions = new HashMap<string,MethodInfo>();
+			try
+			{
+				JavascriptCompiler.Compile("sqrt(20)", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("Unrecognized method"));
+			}
+		}
+
+		/// <summary>using the default map explicitly</summary>
+		[Test]
+		public virtual void TestDefaultList()
+		{
+			IDictionary<string, MethodInfo> functions = JavascriptCompiler.DEFAULT_FUNCTIONS;
+			var expr = JavascriptCompiler.Compile("sqrt(20)", functions);
+			AreEqual(Math.Sqrt(20), expr.Evaluate(0, null), DELTA);
+		}
+
+		public static double ZeroArgMethod()
+		{
+			return 5;
+		}
+
+		/// <summary>tests a method with no arguments</summary>
+		[Test]
+		public virtual void TestNoArgMethod()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("ZeroArgMethod");
+			var expr = JavascriptCompiler.Compile("foo()", functions);
+			AreEqual(5, expr.Evaluate(0, null), DELTA);
+		}
+
+		public static double OneArgMethod(double arg1)
+		{
+			return 3 + arg1;
+		}
+
+		/// <summary>tests a method with one arguments</summary>
+		[Test]
+		public virtual void TestOneArgMethod()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("OneArgMethod", new []{ typeof(double)});
+			var expr = JavascriptCompiler.Compile("foo(3)", functions);
+			AreEqual(6, expr.Evaluate(0, null), DELTA);
+		}
+
+		public static double ThreeArgMethod(double arg1, double arg2, double arg3)
+		{
+			return arg1 + arg2 + arg3;
+		}
+
+		/// <summary>tests a method with three arguments</summary>
+		[Test]
+		public virtual void TestThreeArgMethod()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("ThreeArgMethod", new []{ typeof(double), typeof(
+				double), typeof(double)});
+			var expr = JavascriptCompiler.Compile("foo(3, 4, 5)", functions);
+			AreEqual(12, expr.Evaluate(0, null), DELTA);
+		}
+
+		/// <summary>tests a map with 2 functions</summary>
+		[Test]
+		public virtual void TestTwoMethods()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("ZeroArgMethod");
+			functions["bar"] = GetType().GetMethod("OneArgMethod", new []{typeof(double)});
+			var expr = JavascriptCompiler.Compile("foo() + bar(3)", functions);
+			AreEqual(11, expr.Evaluate(0, null), DELTA);
+		}
+
+		public static string BogusReturnType()
+		{
+			return "bogus!";
+		}
+
+		/// <summary>wrong return type: must be double</summary>
+		[Test]
+		public virtual void TestWrongReturnType()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("BogusReturnType");
+			try
+			{
+				JavascriptCompiler.Compile("foo()", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("does not return a double"));
+			}
+		}
+
+		public static double BogusParameterType(string s)
+		{
+			return 0;
+		}
+
+		/// <summary>wrong param type: must be doubles</summary>
+		[Test]
+		public virtual void TestWrongParameterType()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("BogusParameterType", new []{ typeof(string)});
+			try
+			{
+				JavascriptCompiler.Compile("foo(2)", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("must take only double parameters"
+					));
+			}
+		}
+
+		public virtual double NonStaticMethod()
+		{
+			return 0;
+		}
+
+		/// <summary>wrong modifiers: must be static</summary>
+		[Test]
+		public virtual void TestWrongNotStatic()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("NonStaticMethod");
+			try
+			{
+				JavascriptCompiler.Compile("foo()", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("is not static"));
+			}
+		}
+
+		internal static double NonPublicMethod()
+		{
+			return 0;
+		}
+
+		/// <summary>wrong modifiers: must be public</summary>
+		[Test]
+		public virtual void TestWrongNotPublic()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("NonPublicMethod",BindingFlags.NonPublic|BindingFlags.Static);
+				
+			try
+			{
+				JavascriptCompiler.Compile("foo()", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("is not public"));
+			}
+		}
+
+		internal class NestedNotPublic
+		{
+			public static double Method()
+			{
+				return 0;
+			}
+		}
+
+		/// <summary>wrong class modifiers: class containing method is not public</summary>
+		[Test]
+		public virtual void TestWrongNestedNotPublic()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = typeof(NestedNotPublic).GetMethod("Method");
+			try
+			{
+				JavascriptCompiler.Compile("foo()", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("is not public"));
+			}
+		}
+
+		
+		internal static string MESSAGE = "This should not happen but it happens";
+
+		public class StaticThrowingException
+		{
+			public static double Method()
+			{
+				throw new ArithmeticException(MESSAGE);
+			}
+		}
+
+		/// <summary>the method throws an exception.</summary>
+		/// <remarks>the method throws an exception. We should check the stack trace that it contains the source code of the expression as file name.
+		/// 	</remarks>
+		[Test]
+		public virtual void TestThrowingException()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = typeof(StaticThrowingException).GetMethod("Method");
+			string source = "3 * foo() / 5";
+			var expr = JavascriptCompiler.Compile(source, functions);
+			try
+			{
+				expr.Evaluate(0, null);
+				Fail();
+			}
+			catch (ArithmeticException e)
+			{
+				AreEqual(MESSAGE, e.Message);
+				StringWriter sw = new StringWriter();
+				e.printStackTrace();
+                //.NET Port
+                IsTrue(e.StackTrace.Contains("Lucene.Net.Expressions.CompiledExpression.Evaluate(Int32 , FunctionValues[] )"));
+			}
+		}
+
+		/// <summary>test that namespaces work with custom expressions.</summary>
+		/// <remarks>test that namespaces work with custom expressions.</remarks>
+		[Test]
+		public virtual void TestNamespaces()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo.bar"] = GetType().GetMethod("ZeroArgMethod");
+			string source = "foo.bar()";
+			var expr = JavascriptCompiler.Compile(source, functions);
+			AreEqual(5, expr.Evaluate(0, null), DELTA);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptCompiler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptCompiler.cs b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptCompiler.cs
new file mode 100644
index 0000000..41da6b3
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptCompiler.cs
@@ -0,0 +1,187 @@
+using System;
+using Lucene.Net.Expressions.JS;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions.JS
+{
+	public class TestJavascriptCompiler : Util.LuceneTestCase
+	{
+		[Test]
+		public virtual void TestValidCompiles()
+		{
+			IsNotNull(JavascriptCompiler.Compile("100"));
+			IsNotNull(JavascriptCompiler.Compile("valid0+100"));
+			IsNotNull(JavascriptCompiler.Compile("valid0+\n100"));
+			IsNotNull(JavascriptCompiler.Compile("logn(2, 20+10-5.0)"));
+		}
+
+		[Test]
+		public virtual void TestValidNamespaces()
+		{
+			IsNotNull(JavascriptCompiler.Compile("object.valid0"));
+			IsNotNull(JavascriptCompiler.Compile("object0.object1.valid1"));
+		}
+
+        //TODO: change all exceptions to ParseExceptions
+		[Test]
+		public virtual void TestInvalidNamespaces()
+		{
+			try
+			{
+				JavascriptCompiler.Compile("object.0invalid");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			//expected
+			try
+			{
+				JavascriptCompiler.Compile("0.invalid");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			//expected
+			try
+			{
+				JavascriptCompiler.Compile("object..invalid");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			//expected
+			try
+			{
+				JavascriptCompiler.Compile(".invalid");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+		}
+
+		//expected
+		[Test]
+		public virtual void TestInvalidCompiles()
+		{
+			try
+			{
+				JavascriptCompiler.Compile("100 100");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("7*/-8");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("0y1234");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("500EE");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("500.5EE");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+		}
+
+		[Test]
+		public virtual void TestEmpty()
+		{
+			try
+			{
+				JavascriptCompiler.Compile(string.Empty);
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("()");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("   \r\n   \n \t");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+		}
+
+		// expected exception
+		[Test]
+		public virtual void TestNull()
+		{
+			try
+			{
+				JavascriptCompiler.Compile(null);
+				Fail();
+			}
+			catch (ArgumentNullException)
+			{
+			}
+		}
+
+		// expected exception
+		[Test]
+		public virtual void TestWrongArity()
+		{
+			try
+			{
+				JavascriptCompiler.Compile("tan()");
+				Fail();
+			}
+			catch (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("arguments for method call"
+					));
+			}
+			try
+			{
+				JavascriptCompiler.Compile("tan(1, 1)");
+				Fail();
+			}
+			catch (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("arguments for method call"
+					));
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptFunction.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptFunction.cs b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptFunction.cs
new file mode 100644
index 0000000..3d39f1d
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptFunction.cs
@@ -0,0 +1,309 @@
+using System;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions.JS
+{
+	public class TestJavascriptFunction : Util.LuceneTestCase
+	{
+		private static double DELTA = 0.0000001;
+
+		
+		private void AssertEvaluatesTo(string expression, double expected)
+		{
+			Expression evaluator = JavascriptCompiler.Compile(expression);
+			double actual = evaluator.Evaluate(0, null);
+			AreEqual(expected, actual, DELTA);
+		}
+
+		[Test]
+		public virtual void TestAbsMethod()
+		{
+			AssertEvaluatesTo("abs(0)", 0);
+			AssertEvaluatesTo("abs(119)", 119);
+			AssertEvaluatesTo("abs(119)", 119);
+			AssertEvaluatesTo("abs(1)", 1);
+			AssertEvaluatesTo("abs(-1)", 1);
+		}
+
+		[Test]
+		public virtual void TestAcosMethod()
+		{
+			AssertEvaluatesTo("acos(-1)", Math.PI);
+			AssertEvaluatesTo("acos(-0.8660254)", Math.PI * 5 / 6);
+			AssertEvaluatesTo("acos(-0.7071068)", Math.PI * 3 / 4);
+			AssertEvaluatesTo("acos(-0.5)", Math.PI * 2 / 3);
+			AssertEvaluatesTo("acos(0)", Math.PI / 2);
+			AssertEvaluatesTo("acos(0.5)", Math.PI / 3);
+			AssertEvaluatesTo("acos(0.7071068)", Math.PI / 4);
+			AssertEvaluatesTo("acos(0.8660254)", Math.PI / 6);
+			AssertEvaluatesTo("acos(1)", 0);
+		}
+
+		[Test]
+		public virtual void TestAcoshMethod()
+		{
+			AssertEvaluatesTo("acosh(1)", 0);
+			AssertEvaluatesTo("acosh(2.5)", 1.5667992369724109);
+			AssertEvaluatesTo("acosh(1234567.89)", 14.719378760739708);
+		}
+
+		[Test]
+		public virtual void TestAsinMethod()
+		{
+			AssertEvaluatesTo("asin(-1)", -Math.PI / 2);
+			AssertEvaluatesTo("asin(-0.8660254)", -Math.PI / 3);
+			AssertEvaluatesTo("asin(-0.7071068)", -Math.PI / 4);
+			AssertEvaluatesTo("asin(-0.5)", -Math.PI / 6);
+			AssertEvaluatesTo("asin(0)", 0);
+			AssertEvaluatesTo("asin(0.5)", Math.PI / 6);
+			AssertEvaluatesTo("asin(0.7071068)", Math.PI / 4);
+			AssertEvaluatesTo("asin(0.8660254)", Math.PI / 3);
+			AssertEvaluatesTo("asin(1)", Math.PI / 2);
+		}
+
+		[Test]
+		public virtual void TestAsinhMethod()
+		{
+			AssertEvaluatesTo("asinh(-1234567.89)", -14.719378760740035);
+			AssertEvaluatesTo("asinh(-2.5)", -1.6472311463710958);
+			AssertEvaluatesTo("asinh(-1)", -0.8813735870195429);
+			AssertEvaluatesTo("asinh(0)", 0);
+			AssertEvaluatesTo("asinh(1)", 0.8813735870195429);
+			AssertEvaluatesTo("asinh(2.5)", 1.6472311463710958);
+			AssertEvaluatesTo("asinh(1234567.89)", 14.719378760740035);
+		}
+
+		[Test]
+		public virtual void TestAtanMethod()
+		{
+			AssertEvaluatesTo("atan(-1.732050808)", -Math.PI / 3);
+			AssertEvaluatesTo("atan(-1)", -Math.PI / 4);
+			AssertEvaluatesTo("atan(-0.577350269)", -Math.PI / 6);
+			AssertEvaluatesTo("atan(0)", 0);
+			AssertEvaluatesTo("atan(0.577350269)", Math.PI / 6);
+			AssertEvaluatesTo("atan(1)", Math.PI / 4);
+			AssertEvaluatesTo("atan(1.732050808)", Math.PI / 3);
+		}
+
+		[Test]
+		public virtual void TestAtan2Method()
+		{
+			AssertEvaluatesTo("atan2(+0,+0)", +0.0);
+			AssertEvaluatesTo("atan2(+0,-0)", +Math.PI);
+			AssertEvaluatesTo("atan2(-0,+0)", -0.0);
+			AssertEvaluatesTo("atan2(-0,-0)", -Math.PI);
+			AssertEvaluatesTo("atan2(2,2)", Math.PI / 4);
+			AssertEvaluatesTo("atan2(-2,2)", -Math.PI / 4);
+			AssertEvaluatesTo("atan2(2,-2)", Math.PI * 3 / 4);
+			AssertEvaluatesTo("atan2(-2,-2)", -Math.PI * 3 / 4);
+		}
+
+		[Test]
+		public virtual void TestAtanhMethod()
+		{
+			AssertEvaluatesTo("atanh(-1)", double.NegativeInfinity);
+			AssertEvaluatesTo("atanh(-0.5)", -0.5493061443340549);
+			AssertEvaluatesTo("atanh(0)", 0);
+			AssertEvaluatesTo("atanh(0.5)", 0.5493061443340549);
+			AssertEvaluatesTo("atanh(1)", double.PositiveInfinity);
+		}
+
+		[Test]
+		public virtual void TestCeilMethod()
+		{
+			AssertEvaluatesTo("ceil(0)", 0);
+			AssertEvaluatesTo("ceil(0.1)", 1);
+			AssertEvaluatesTo("ceil(0.9)", 1);
+			AssertEvaluatesTo("ceil(25.2)", 26);
+			AssertEvaluatesTo("ceil(-0.1)", 0);
+			AssertEvaluatesTo("ceil(-0.9)", 0);
+			AssertEvaluatesTo("ceil(-1.1)", -1);
+		}
+
+		[Test]
+		public virtual void TestCosMethod()
+		{
+			AssertEvaluatesTo("cos(0)", 1);
+			AssertEvaluatesTo("cos(" + Math.PI / 2 + ")", 0);
+			AssertEvaluatesTo("cos(" + -Math.PI / 2 + ")", 0);
+			AssertEvaluatesTo("cos(" + Math.PI / 4 + ")", 0.7071068);
+			AssertEvaluatesTo("cos(" + -Math.PI / 4 + ")", 0.7071068);
+			AssertEvaluatesTo("cos(" + Math.PI * 2 / 3 + ")", -0.5);
+			AssertEvaluatesTo("cos(" + -Math.PI * 2 / 3 + ")", -0.5);
+			AssertEvaluatesTo("cos(" + Math.PI / 6 + ")", 0.8660254);
+			AssertEvaluatesTo("cos(" + -Math.PI / 6 + ")", 0.8660254);
+		}
+
+		[Test]
+		public virtual void TestCoshMethod()
+		{
+			AssertEvaluatesTo("cosh(0)", 1);
+			AssertEvaluatesTo("cosh(-1)", 1.5430806348152437);
+			AssertEvaluatesTo("cosh(1)", 1.5430806348152437);
+			AssertEvaluatesTo("cosh(-0.5)", 1.1276259652063807);
+			AssertEvaluatesTo("cosh(0.5)", 1.1276259652063807);
+			AssertEvaluatesTo("cosh(-12.3456789)", 114982.09728671524);
+			AssertEvaluatesTo("cosh(12.3456789)", 114982.09728671524);
+		}
+
+		[Test]
+		public virtual void TestExpMethod()
+		{
+			AssertEvaluatesTo("exp(0)", 1);
+			AssertEvaluatesTo("exp(-1)", 0.36787944117);
+			AssertEvaluatesTo("exp(1)", 2.71828182846);
+			AssertEvaluatesTo("exp(-0.5)", 0.60653065971);
+			AssertEvaluatesTo("exp(0.5)", 1.6487212707);
+			AssertEvaluatesTo("exp(-12.3456789)", 0.0000043485);
+			AssertEvaluatesTo("exp(12.3456789)", 229964.194569);
+		}
+
+		[Test]
+		public virtual void TestFloorMethod()
+		{
+			AssertEvaluatesTo("floor(0)", 0);
+			AssertEvaluatesTo("floor(0.1)", 0);
+			AssertEvaluatesTo("floor(0.9)", 0);
+			AssertEvaluatesTo("floor(25.2)", 25);
+			AssertEvaluatesTo("floor(-0.1)", -1);
+			AssertEvaluatesTo("floor(-0.9)", -1);
+			AssertEvaluatesTo("floor(-1.1)", -2);
+		}
+
+		[Test]
+		public virtual void TestHaversinMethod()
+		{
+			AssertEvaluatesTo("haversin(40.7143528,-74.0059731,40.759011,-73.9844722)", 5.284299568309
+				);
+		}
+
+		[Test]
+		public virtual void TestLnMethod()
+		{
+			AssertEvaluatesTo("ln(0)", double.NegativeInfinity);
+			AssertEvaluatesTo("ln(" + Math.E + ")", 1);
+			AssertEvaluatesTo("ln(-1)", double.NaN);
+			AssertEvaluatesTo("ln(1)", 0);
+			AssertEvaluatesTo("ln(0.5)", -0.69314718056);
+			AssertEvaluatesTo("ln(12.3456789)", 2.51330611521);
+		}
+
+		[Test]
+		public virtual void TestLog10Method()
+		{
+			AssertEvaluatesTo("log10(0)", double.NegativeInfinity);
+			AssertEvaluatesTo("log10(1)", 0);
+			AssertEvaluatesTo("log10(-1)", double.NaN);
+			AssertEvaluatesTo("log10(0.5)", -0.3010299956639812);
+			AssertEvaluatesTo("log10(12.3456789)", 1.0915149771692705);
+		}
+
+		[Test]
+		public virtual void TestLognMethod()
+		{
+			AssertEvaluatesTo("logn(2, 0)", double.NegativeInfinity);
+			AssertEvaluatesTo("logn(2, 1)", 0);
+			AssertEvaluatesTo("logn(2, -1)", double.NaN);
+			AssertEvaluatesTo("logn(2, 0.5)", -1);
+			AssertEvaluatesTo("logn(2, 12.3456789)", 3.6259342686489378);
+			AssertEvaluatesTo("logn(2.5, 0)", double.NegativeInfinity);
+			AssertEvaluatesTo("logn(2.5, 1)", 0);
+			AssertEvaluatesTo("logn(2.5, -1)", double.NaN);
+			AssertEvaluatesTo("logn(2.5, 0.5)", -0.75647079736603);
+			AssertEvaluatesTo("logn(2.5, 12.3456789)", 2.7429133874016745);
+		}
+
+		[Test]
+		public virtual void TestMaxMethod()
+		{
+			AssertEvaluatesTo("max(0, 0)", 0);
+			AssertEvaluatesTo("max(1, 0)", 1);
+			AssertEvaluatesTo("max(0, -1)", 0);
+			AssertEvaluatesTo("max(-1, 0)", 0);
+			AssertEvaluatesTo("max(25, 23)", 25);
+		}
+
+		[Test]
+		public virtual void TestMinMethod()
+		{
+			AssertEvaluatesTo("min(0, 0)", 0);
+			AssertEvaluatesTo("min(1, 0)", 0);
+			AssertEvaluatesTo("min(0, -1)", -1);
+			AssertEvaluatesTo("min(-1, 0)", -1);
+			AssertEvaluatesTo("min(25, 23)", 23);
+		}
+
+		[Test]
+		public virtual void TestPowMethod()
+		{
+			AssertEvaluatesTo("pow(0, 0)", 1);
+			AssertEvaluatesTo("pow(0.1, 2)", 0.01);
+			AssertEvaluatesTo("pow(0.9, -1)", 1.1111111111111112);
+			AssertEvaluatesTo("pow(2.2, -2.5)", 0.13929749224447147);
+			AssertEvaluatesTo("pow(5, 3)", 125);
+			AssertEvaluatesTo("pow(-0.9, 5)", -0.59049);
+			AssertEvaluatesTo("pow(-1.1, 2)", 1.21);
+		}
+
+		[Test]
+		public virtual void TestSinMethod()
+		{
+			AssertEvaluatesTo("sin(0)", 0);
+			AssertEvaluatesTo("sin(" + Math.PI / 2 + ")", 1);
+			AssertEvaluatesTo("sin(" + -Math.PI / 2 + ")", -1);
+			AssertEvaluatesTo("sin(" + Math.PI / 4 + ")", 0.7071068);
+			AssertEvaluatesTo("sin(" + -Math.PI / 4 + ")", -0.7071068);
+			AssertEvaluatesTo("sin(" + Math.PI * 2 / 3 + ")", 0.8660254);
+			AssertEvaluatesTo("sin(" + -Math.PI * 2 / 3 + ")", -0.8660254);
+			AssertEvaluatesTo("sin(" + Math.PI / 6 + ")", 0.5);
+			AssertEvaluatesTo("sin(" + -Math.PI / 6 + ")", -0.5);
+		}
+
+		[Test]
+		public virtual void TestSinhMethod()
+		{
+			AssertEvaluatesTo("sinh(0)", 0);
+			AssertEvaluatesTo("sinh(-1)", -1.1752011936438014);
+			AssertEvaluatesTo("sinh(1)", 1.1752011936438014);
+			AssertEvaluatesTo("sinh(-0.5)", -0.52109530549);
+			AssertEvaluatesTo("sinh(0.5)", 0.52109530549);
+			AssertEvaluatesTo("sinh(-12.3456789)", -114982.09728236674);
+			AssertEvaluatesTo("sinh(12.3456789)", 114982.09728236674);
+		}
+
+		[Test]
+		public virtual void TestSqrtMethod()
+		{
+			AssertEvaluatesTo("sqrt(0)", 0);
+			AssertEvaluatesTo("sqrt(-1)", double.NaN);
+			AssertEvaluatesTo("sqrt(0.49)", 0.7);
+			AssertEvaluatesTo("sqrt(49)", 7);
+		}
+
+		[Test]
+		public virtual void TestTanMethod()
+		{
+			AssertEvaluatesTo("tan(0)", 0);
+			AssertEvaluatesTo("tan(-1)", -1.55740772465);
+			AssertEvaluatesTo("tan(1)", 1.55740772465);
+			AssertEvaluatesTo("tan(-0.5)", -0.54630248984);
+			AssertEvaluatesTo("tan(0.5)", 0.54630248984);
+			AssertEvaluatesTo("tan(-1.3)", -3.60210244797);
+			AssertEvaluatesTo("tan(1.3)", 3.60210244797);
+		}
+
+		[Test]
+		public virtual void TestTanhMethod()
+		{
+			AssertEvaluatesTo("tanh(0)", 0);
+			AssertEvaluatesTo("tanh(-1)", -0.76159415595);
+			AssertEvaluatesTo("tanh(1)", 0.76159415595);
+			AssertEvaluatesTo("tanh(-0.5)", -0.46211715726);
+			AssertEvaluatesTo("tanh(0.5)", 0.46211715726);
+			AssertEvaluatesTo("tanh(-12.3456789)", -0.99999999996);
+			AssertEvaluatesTo("tanh(12.3456789)", 0.99999999996);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptOperations.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptOperations.cs b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptOperations.cs
new file mode 100644
index 0000000..07b2fa9
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptOperations.cs
@@ -0,0 +1,373 @@
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions.JS
+{
+	public class TestJavascriptOperations : Util.LuceneTestCase
+	{
+		
+		private void AssertEvaluatesTo(string expression, long expected)
+		{
+			Expression evaluator = JavascriptCompiler.Compile(expression);
+			long actual = (long)evaluator.Evaluate(0, null);
+			AreEqual(expected, actual);
+		}
+
+		[Test]
+		public virtual void TestNegationOperation()
+		{
+			AssertEvaluatesTo("-1", -1);
+			AssertEvaluatesTo("--1", 1);
+			AssertEvaluatesTo("-(-1)", 1);
+			AssertEvaluatesTo("-0", 0);
+			AssertEvaluatesTo("--0", 0);
+		}
+
+		[Test]
+		public virtual void TestAddOperation()
+		{
+			AssertEvaluatesTo("1+1", 2);
+			AssertEvaluatesTo("1+0.5+0.5", 2);
+			AssertEvaluatesTo("5+10", 15);
+			AssertEvaluatesTo("1+1+2", 4);
+			AssertEvaluatesTo("(1+1)+2", 4);
+			AssertEvaluatesTo("1+(1+2)", 4);
+			AssertEvaluatesTo("0+1", 1);
+			AssertEvaluatesTo("1+0", 1);
+			AssertEvaluatesTo("0+0", 0);
+		}
+
+		[Test]
+		public virtual void TestSubtractOperation()
+		{
+			AssertEvaluatesTo("1-1", 0);
+			AssertEvaluatesTo("5-10", -5);
+			AssertEvaluatesTo("1-0.5-0.5", 0);
+			AssertEvaluatesTo("1-1-2", -2);
+			AssertEvaluatesTo("(1-1)-2", -2);
+			AssertEvaluatesTo("1-(1-2)", 2);
+			AssertEvaluatesTo("0-1", -1);
+			AssertEvaluatesTo("1-0", 1);
+			AssertEvaluatesTo("0-0", 0);
+		}
+
+		[Test]
+		public virtual void TestMultiplyOperation()
+		{
+			AssertEvaluatesTo("1*1", 1);
+			AssertEvaluatesTo("5*10", 50);
+			AssertEvaluatesTo("50*0.1", 5);
+			AssertEvaluatesTo("1*1*2", 2);
+			AssertEvaluatesTo("(1*1)*2", 2);
+			AssertEvaluatesTo("1*(1*2)", 2);
+			AssertEvaluatesTo("10*0", 0);
+			AssertEvaluatesTo("0*0", 0);
+		}
+
+		[Test]
+		public virtual void TestDivisionOperation()
+		{
+			AssertEvaluatesTo("1*1", 1);
+			AssertEvaluatesTo("10/5", 2);
+			AssertEvaluatesTo("10/0.5", 20);
+			AssertEvaluatesTo("10/5/2", 1);
+			AssertEvaluatesTo("(27/9)/3", 1);
+			AssertEvaluatesTo("27/(9/3)", 9);
+			AssertEvaluatesTo("1/0", 9223372036854775807L);
+		}
+
+		[Test]
+		public virtual void TestModuloOperation()
+		{
+			AssertEvaluatesTo("1%1", 0);
+			AssertEvaluatesTo("10%3", 1);
+			AssertEvaluatesTo("10%3%2", 1);
+			AssertEvaluatesTo("(27%10)%4", 3);
+			AssertEvaluatesTo("27%(9%5)", 3);
+		}
+
+		[Test]
+		public virtual void TestLessThanOperation()
+		{
+			AssertEvaluatesTo("1 < 1", 0);
+			AssertEvaluatesTo("2 < 1", 0);
+			AssertEvaluatesTo("1 < 2", 1);
+			AssertEvaluatesTo("2 < 1 < 3", 1);
+			AssertEvaluatesTo("2 < (1 < 3)", 0);
+			AssertEvaluatesTo("(2 < 1) < 1", 1);
+			AssertEvaluatesTo("-1 < -2", 0);
+			AssertEvaluatesTo("-1 < 0", 1);
+		}
+
+		[Test]
+		public virtual void TestLessThanEqualsOperation()
+		{
+			AssertEvaluatesTo("1 <= 1", 1);
+			AssertEvaluatesTo("2 <= 1", 0);
+			AssertEvaluatesTo("1 <= 2", 1);
+			AssertEvaluatesTo("1 <= 1 <= 0", 0);
+			AssertEvaluatesTo("-1 <= -1", 1);
+			AssertEvaluatesTo("-1 <= 0", 1);
+			AssertEvaluatesTo("-1 <= -2", 0);
+			AssertEvaluatesTo("-1 <= 0", 1);
+		}
+
+		[Test]
+		public virtual void TestGreaterThanOperation()
+		{
+			AssertEvaluatesTo("1 > 1", 0);
+			AssertEvaluatesTo("2 > 1", 1);
+			AssertEvaluatesTo("1 > 2", 0);
+			AssertEvaluatesTo("2 > 1 > 3", 0);
+			AssertEvaluatesTo("2 > (1 > 3)", 1);
+			AssertEvaluatesTo("(2 > 1) > 1", 0);
+			AssertEvaluatesTo("-1 > -2", 1);
+			AssertEvaluatesTo("-1 > 0", 0);
+		}
+
+		[Test]
+		public virtual void TestGreaterThanEqualsOperation()
+		{
+			AssertEvaluatesTo("1 >= 1", 1);
+			AssertEvaluatesTo("2 >= 1", 1);
+			AssertEvaluatesTo("1 >= 2", 0);
+			AssertEvaluatesTo("1 >= 1 >= 0", 1);
+			AssertEvaluatesTo("-1 >= -1", 1);
+			AssertEvaluatesTo("-1 >= 0", 0);
+			AssertEvaluatesTo("-1 >= -2", 1);
+			AssertEvaluatesTo("-1 >= 0", 0);
+		}
+
+		[Test]
+		public virtual void TestEqualsOperation()
+		{
+			AssertEvaluatesTo("1 == 1", 1);
+			AssertEvaluatesTo("0 == 0", 1);
+			AssertEvaluatesTo("-1 == -1", 1);
+			AssertEvaluatesTo("1.1 == 1.1", 1);
+			AssertEvaluatesTo("0.9 == 0.9", 1);
+			AssertEvaluatesTo("-0 == 0", 1);
+			AssertEvaluatesTo("0 == 1", 0);
+			AssertEvaluatesTo("1 == 2", 0);
+			AssertEvaluatesTo("-1 == 1", 0);
+			AssertEvaluatesTo("-1 == 0", 0);
+			AssertEvaluatesTo("-2 == 1", 0);
+			AssertEvaluatesTo("-2 == -1", 0);
+		}
+
+		[Test]
+		public virtual void TestNotEqualsOperation()
+		{
+			AssertEvaluatesTo("1 != 1", 0);
+			AssertEvaluatesTo("0 != 0", 0);
+			AssertEvaluatesTo("-1 != -1", 0);
+			AssertEvaluatesTo("1.1 != 1.1", 0);
+			AssertEvaluatesTo("0.9 != 0.9", 0);
+			AssertEvaluatesTo("-0 != 0", 0);
+			AssertEvaluatesTo("0 != 1", 1);
+			AssertEvaluatesTo("1 != 2", 1);
+			AssertEvaluatesTo("-1 != 1", 1);
+			AssertEvaluatesTo("-1 != 0", 1);
+			AssertEvaluatesTo("-2 != 1", 1);
+			AssertEvaluatesTo("-2 != -1", 1);
+		}
+
+		[Test]
+		public virtual void TestBoolNotOperation()
+		{
+			AssertEvaluatesTo("!1", 0);
+			AssertEvaluatesTo("!!1", 1);
+			AssertEvaluatesTo("!0", 1);
+			AssertEvaluatesTo("!!0", 0);
+			AssertEvaluatesTo("!-1", 0);
+			AssertEvaluatesTo("!2", 0);
+			AssertEvaluatesTo("!-2", 0);
+		}
+
+		[Test]
+		public virtual void TestBoolAndOperation()
+		{
+			AssertEvaluatesTo("1 && 1", 1);
+			AssertEvaluatesTo("1 && 0", 0);
+			AssertEvaluatesTo("0 && 1", 0);
+			AssertEvaluatesTo("0 && 0", 0);
+			AssertEvaluatesTo("-1 && -1", 1);
+			AssertEvaluatesTo("-1 && 0", 0);
+			AssertEvaluatesTo("0 && -1", 0);
+			AssertEvaluatesTo("-0 && -0", 0);
+		}
+
+		[Test]
+		public virtual void TestBoolOrOperation()
+		{
+			AssertEvaluatesTo("1 || 1", 1);
+			AssertEvaluatesTo("1 || 0", 1);
+			AssertEvaluatesTo("0 || 1", 1);
+			AssertEvaluatesTo("0 || 0", 0);
+			AssertEvaluatesTo("-1 || -1", 1);
+			AssertEvaluatesTo("-1 || 0", 1);
+			AssertEvaluatesTo("0 || -1", 1);
+			AssertEvaluatesTo("-0 || -0", 0);
+		}
+
+		[Test]
+		public virtual void TestConditionalOperation()
+		{
+			AssertEvaluatesTo("1 ? 2 : 3", 2);
+			AssertEvaluatesTo("-1 ? 2 : 3", 2);
+			AssertEvaluatesTo("0 ? 2 : 3", 3);
+			AssertEvaluatesTo("1 ? 2 ? 3 : 4 : 5", 3);
+			AssertEvaluatesTo("0 ? 2 ? 3 : 4 : 5", 5);
+			AssertEvaluatesTo("1 ? 0 ? 3 : 4 : 5", 4);
+			AssertEvaluatesTo("1 ? 2 : 3 ? 4 : 5", 2);
+			AssertEvaluatesTo("0 ? 2 : 3 ? 4 : 5", 4);
+			AssertEvaluatesTo("0 ? 2 : 0 ? 4 : 5", 5);
+			AssertEvaluatesTo("(1 ? 1 : 0) ? 3 : 4", 3);
+			AssertEvaluatesTo("(0 ? 1 : 0) ? 3 : 4", 4);
+		}
+
+		[Test]
+		public virtual void TestBitShiftLeft()
+		{
+			AssertEvaluatesTo("1 << 1", 2);
+			AssertEvaluatesTo("2 << 1", 4);
+			AssertEvaluatesTo("-1 << 31", -2147483648);
+			AssertEvaluatesTo("3 << 5", 96);
+			AssertEvaluatesTo("-5 << 3", -40);
+			AssertEvaluatesTo("4195 << 7", 536960);
+			AssertEvaluatesTo("4195 << 66", 16780);
+			AssertEvaluatesTo("4195 << 6", 268480);
+			AssertEvaluatesTo("4195 << 70", 268480);
+			AssertEvaluatesTo("-4195 << 70", -268480);
+			AssertEvaluatesTo("-15 << 62", 4611686018427387904L);
+		}
+
+		[Test]
+		public virtual void TestBitShiftRight()
+		{
+			AssertEvaluatesTo("1 >> 1", 0);
+			AssertEvaluatesTo("2 >> 1", 1);
+			AssertEvaluatesTo("-1 >> 5", -1);
+			AssertEvaluatesTo("-2 >> 30", -1);
+			AssertEvaluatesTo("-5 >> 1", -3);
+			AssertEvaluatesTo("536960 >> 7", 4195);
+			AssertEvaluatesTo("16780 >> 66", 4195);
+			AssertEvaluatesTo("268480 >> 6", 4195);
+			AssertEvaluatesTo("268480 >> 70", 4195);
+			AssertEvaluatesTo("-268480 >> 70", -4195);
+			AssertEvaluatesTo("-2147483646 >> 1", -1073741823);
+		}
+
+		[Test]
+		public virtual void TestBitShiftRightUnsigned()
+		{
+			AssertEvaluatesTo("1 >>> 1", 0);
+			AssertEvaluatesTo("2 >>> 1", 1);
+			AssertEvaluatesTo("-1 >>> 37", 134217727);
+			AssertEvaluatesTo("-2 >>> 62", 3);
+			AssertEvaluatesTo("-5 >>> 33", 2147483647);
+			AssertEvaluatesTo("536960 >>> 7", 4195);
+			AssertEvaluatesTo("16780 >>> 66", 4195);
+			AssertEvaluatesTo("268480 >>> 6", 4195);
+			AssertEvaluatesTo("268480 >>> 70", 4195);
+			AssertEvaluatesTo("-268480 >>> 102", 67108863);
+			AssertEvaluatesTo("2147483648 >>> 1", 1073741824);
+		}
+
+		[Test]
+		public virtual void TestBitwiseAnd()
+		{
+			AssertEvaluatesTo("4 & 4", 4);
+			AssertEvaluatesTo("3 & 2", 2);
+			AssertEvaluatesTo("7 & 3", 3);
+			AssertEvaluatesTo("-1 & -1", -1);
+			AssertEvaluatesTo("-1 & 25", 25);
+			AssertEvaluatesTo("3 & 7", 3);
+			AssertEvaluatesTo("0 & 1", 0);
+			AssertEvaluatesTo("1 & 0", 0);
+		}
+
+		[Test]
+		public virtual void TestBitwiseOr()
+		{
+			AssertEvaluatesTo("4 | 4", 4);
+			AssertEvaluatesTo("5 | 2", 7);
+			AssertEvaluatesTo("7 | 3", 7);
+			AssertEvaluatesTo("-1 | -5", -1);
+			AssertEvaluatesTo("-1 | 25", -1);
+			AssertEvaluatesTo("-100 | 15", -97);
+			AssertEvaluatesTo("0 | 1", 1);
+			AssertEvaluatesTo("1 | 0", 1);
+		}
+
+		[Test]
+		public virtual void TestBitwiseXor()
+		{
+			AssertEvaluatesTo("4 ^ 4", 0);
+			AssertEvaluatesTo("5 ^ 2", 7);
+			AssertEvaluatesTo("15 ^ 3", 12);
+			AssertEvaluatesTo("-1 ^ -5", 4);
+			AssertEvaluatesTo("-1 ^ 25", -26);
+			AssertEvaluatesTo("-100 ^ 15", -109);
+			AssertEvaluatesTo("0 ^ 1", 1);
+			AssertEvaluatesTo("1 ^ 0", 1);
+			AssertEvaluatesTo("0 ^ 0", 0);
+		}
+
+		[Test]
+		public virtual void TestBitwiseNot()
+		{
+			AssertEvaluatesTo("~-5", 4);
+			AssertEvaluatesTo("~25", -26);
+			AssertEvaluatesTo("~0", -1);
+			AssertEvaluatesTo("~-1", 0);
+		}
+
+		[Test]
+		public virtual void TestDecimalConst()
+		{
+			AssertEvaluatesTo("0", 0);
+			AssertEvaluatesTo("1", 1);
+			AssertEvaluatesTo("123456789", 123456789);
+			AssertEvaluatesTo("5.6E2", 560);
+			AssertEvaluatesTo("5.6E+2", 560);
+			AssertEvaluatesTo("500E-2", 5);
+		}
+
+		[Test]
+		public virtual void TestHexConst()
+		{
+			AssertEvaluatesTo("0x0", 0);
+			AssertEvaluatesTo("0x1", 1);
+			AssertEvaluatesTo("0xF", 15);
+			AssertEvaluatesTo("0x1234ABCDEF", 78193085935L);
+			AssertEvaluatesTo("1 << 0x1", 1 << unchecked((int)(0x1)));
+			AssertEvaluatesTo("1 << 0xA", 1 << unchecked((int)(0xA)));
+			AssertEvaluatesTo("0x1 << 2", unchecked((int)(0x1)) << 2);
+			AssertEvaluatesTo("0xA << 2", unchecked((int)(0xA)) << 2);
+		}
+
+		[Test]
+		public virtual void TestHexConst2()
+		{
+			AssertEvaluatesTo("0X0", 0);
+			AssertEvaluatesTo("0X1", 1);
+			AssertEvaluatesTo("0XF", 15);
+			AssertEvaluatesTo("0X1234ABCDEF", 78193085935L);
+		}
+
+		[Test]
+		public virtual void TestOctalConst()
+		{
+			AssertEvaluatesTo("00", 0);
+			AssertEvaluatesTo("01", 1);
+			AssertEvaluatesTo("010", 8);
+			AssertEvaluatesTo("0123456777", 21913087);
+			AssertEvaluatesTo("1 << 01", 1 << 0x1);
+			AssertEvaluatesTo("1 << 010", 1 << 0x8);
+			AssertEvaluatesTo("01 << 2", 0x1 << 2);
+			AssertEvaluatesTo("010 << 2", 0x8 << 2);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/Lucene.Net.Tests.Expressions.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/Lucene.Net.Tests.Expressions.csproj b/src/Lucene.Net.Tests.Expressions/Lucene.Net.Tests.Expressions.csproj
new file mode 100644
index 0000000..c72edd1
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/Lucene.Net.Tests.Expressions.csproj
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{F4873D95-4300-4E83-AFFA-EF796495D0F0}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Lucene.Net.Tests.Expressions</RootNamespace>
+    <AssemblyName>Lucene.Net.Tests.Expressions</AssemblyName>
+    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </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="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="JS\TestCustomFunctions.cs" />
+    <Compile Include="JS\TestJavascriptCompiler.cs" />
+    <Compile Include="JS\TestJavascriptFunction.cs" />
+    <Compile Include="JS\TestJavascriptOperations.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TestDemoExpressions.cs" />
+    <Compile Include="TestExpressionRescorer.cs" />
+    <Compile Include="TestExpressionSortField.cs" />
+    <Compile Include="TestExpressionSorts.cs" />
+    <Compile Include="TestExpressionValidation.cs" />
+    <Compile Include="TestExpressionValueSource.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Lucene.Net.Core\Lucene.Net.csproj">
+      <Project>{5D4AD9BE-1FFB-41AB-9943-25737971BF57}</Project>
+      <Name>Lucene.Net</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Lucene.Net.Expressions\Lucene.Net.Expressions.csproj">
+      <Project>{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}</Project>
+      <Name>Lucene.Net.Expressions</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Lucene.Net.Queries\Lucene.Net.Queries.csproj">
+      <Project>{69D7956C-C2CC-4708-B399-A188FEC384C4}</Project>
+      <Name>Lucene.Net.Queries</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Lucene.Net.TestFramework\Lucene.Net.TestFramework.csproj">
+      <Project>{B2C0D749-CE34-4F62-A15E-00CB2FF5DDB3}</Project>
+      <Name>Lucene.Net.TestFramework</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\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

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/Properties/AssemblyInfo.cs b/src/Lucene.Net.Tests.Expressions/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29105
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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("Lucene.Net.Tests.Expressions")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Lucene.Net.Tests.Expressions")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[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("0c789606-781d-47dc-b391-5ac367fce258")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/TestDemoExpressions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/TestDemoExpressions.cs b/src/Lucene.Net.Tests.Expressions/TestDemoExpressions.cs
new file mode 100644
index 0000000..3adc45a
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/TestDemoExpressions.cs
@@ -0,0 +1,202 @@
+using System;
+using System.Text;
+using Lucene.Net.Documents;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Store;
+using NUnit.Framework;
+using Expression = System.Linq.Expressions.Expression;
+
+namespace Lucene.Net.Tests.Expressions
+{
+	/// <summary>simple demo of using expressions</summary>
+	public class TestDemoExpressions : Util.LuceneTestCase
+	{
+		internal IndexSearcher searcher;
+
+		internal DirectoryReader reader;
+
+		internal Directory dir;
+
+		[SetUp]
+		public override void SetUp()
+		{
+			base.SetUp();
+			dir = NewDirectory();
+			var iw = new RandomIndexWriter(Random(), dir);
+			var doc = new Document
+			{
+			    NewStringField("id", "1", Field.Store.YES),
+			    NewTextField("body", "some contents and more contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 5),
+			    new DoubleField("latitude", 40.759011, Field.Store.NO),
+			    new DoubleField("longitude", -73.9844722, Field.Store.NO)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "2", Field.Store.YES),
+			    NewTextField("body", "another document with different contents", Field.Store
+			        .NO),
+			    new NumericDocValuesField("popularity", 20),
+			    new DoubleField("latitude", 40.718266, Field.Store.NO),
+			    new DoubleField("longitude", -74.007819, Field.Store.NO)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "3", Field.Store.YES),
+			    NewTextField("body", "crappy contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 2),
+			    new DoubleField("latitude", 40.7051157, Field.Store.NO),
+			    new DoubleField("longitude", -74.0088305, Field.Store.NO)
+			};
+		    iw.AddDocument(doc);
+			reader = iw.Reader;
+			searcher = new IndexSearcher(reader);
+			iw.Dispose();
+		}
+
+		[TearDown]
+		public override void TearDown()
+		{
+			reader.Dispose();
+			dir.Dispose();
+			base.TearDown();
+		}
+
+		/// <summary>an example of how to rank by an expression</summary>
+		[Test]
+		public virtual void Test()
+		{
+			// compile an expression:
+			var expr = JavascriptCompiler.Compile("sqrt(_score) + ln(popularity)");
+			// we use SimpleBindings: which just maps variables to SortField instances
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			bindings.Add(new SortField("popularity", SortField.Type_e.INT));
+			// create a sort field and sort by it (reverse order)
+			Sort sort = new Sort(expr.GetSortField(bindings, true));
+			Query query = new TermQuery(new Term("body", "contents"));
+			searcher.Search(query, null, 3, sort);
+		}
+
+		/// <summary>tests the returned sort values are correct</summary>
+		[Test]
+		public virtual void TestSortValues()
+		{
+			var expr = JavascriptCompiler.Compile("sqrt(_score)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			Sort sort = new Sort(expr.GetSortField(bindings, true));
+			Query query = new TermQuery(new Term("body", "contents"));
+			TopFieldDocs td = searcher.Search(query, null, 3, sort, true, true);
+			for (int i = 0; i < 3; i++)
+			{
+				FieldDoc d = (FieldDoc)td.ScoreDocs[i];
+				float expected = (float)Math.Sqrt(d.Score);
+				float actual = (float)((double)d.Fields[0]);
+				AreEqual(expected, actual, CheckHits.ExplainToleranceDelta(expected, actual));
+			}
+		}
+
+		/// <summary>tests same binding used more than once in an expression</summary>
+		[Test]
+		public virtual void TestTwoOfSameBinding()
+		{
+			var expr = JavascriptCompiler.Compile("_score + _score");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			Sort sort = new Sort(expr.GetSortField(bindings, true));
+			Query query = new TermQuery(new Term("body", "contents"));
+			TopFieldDocs td = searcher.Search(query, null, 3, sort, true, true);
+			for (int i = 0; i < 3; i++)
+			{
+				FieldDoc d = (FieldDoc)td.ScoreDocs[i];
+				float expected = 2 * d.Score;
+				float actual = (float)((double)d.Fields[0]);
+				AreEqual(expected, actual, CheckHits.ExplainToleranceDelta
+					(expected, actual));
+			}
+		}
+
+		/// <summary>tests expression referring to another expression</summary>
+		[Test]
+		public virtual void TestExpressionRefersToExpression()
+		{
+			var expr1 = JavascriptCompiler.Compile("_score");
+			var expr2 = JavascriptCompiler.Compile("2*expr1");
+			var bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			bindings.Add("expr1", expr1);
+			Sort sort = new Sort(expr2.GetSortField(bindings, true));
+			Query query = new TermQuery(new Term("body", "contents"));
+			TopFieldDocs td = searcher.Search(query, null, 3, sort, true, true);
+			for (int i = 0; i < 3; i++)
+			{
+				FieldDoc d = (FieldDoc)td.ScoreDocs[i];
+				float expected = 2 * d.Score;
+				float actual = (float)((double)d.Fields[0]);
+				AreEqual(expected, actual, CheckHits.ExplainToleranceDelta
+					(expected, actual));
+			}
+		}
+
+		/// <summary>tests huge amounts of variables in the expression</summary>
+		[Test]
+		public virtual void TestLotsOfBindings()
+		{
+			DoTestLotsOfBindings(byte.MaxValue - 1);
+			DoTestLotsOfBindings(byte.MaxValue);
+			DoTestLotsOfBindings(byte.MaxValue + 1);
+		}
+
+		// TODO: ideally we'd test > Short.MAX_VALUE too, but compilation is currently recursive.
+		// so if we want to test such huge expressions, we need to instead change parser to use an explicit Stack
+		/// <exception cref="System.Exception"></exception>
+		private void DoTestLotsOfBindings(int n)
+		{
+			SimpleBindings bindings = new SimpleBindings();
+			StringBuilder sb = new StringBuilder();
+			for (int i = 0; i < n; i++)
+			{
+				if (i > 0)
+				{
+					sb.Append("+");
+				}
+				sb.Append("x" + i);
+				bindings.Add(new SortField("x" + i, SortField.Type_e.SCORE));
+			}
+			var expr = JavascriptCompiler.Compile(sb.ToString());
+			var sort = new Sort(expr.GetSortField(bindings, true));
+			Query query = new TermQuery(new Term("body", "contents"));
+			TopFieldDocs td = searcher.Search(query, null, 3, sort, true, true);
+			for (int i_1 = 0; i_1 < 3; i_1++)
+			{
+				FieldDoc d = (FieldDoc)td.ScoreDocs[i_1];
+				float expected = n * d.Score;
+				float actual = (float)((double)d.Fields[0]);
+				AreEqual(expected, actual, CheckHits.ExplainToleranceDelta(expected, actual));
+			}
+		}
+
+		[Test]
+		public virtual void TestDistanceSort()
+		{
+			var distance = JavascriptCompiler.Compile("haversin(40.7143528,-74.0059731,latitude,longitude)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("latitude", SortField.Type_e.DOUBLE));
+			bindings.Add(new SortField("longitude", SortField.Type_e.DOUBLE));
+			Sort sort = new Sort(distance.GetSortField(bindings, false));
+			TopFieldDocs td = searcher.Search(new MatchAllDocsQuery(), null, 3, sort);
+			FieldDoc d = (FieldDoc)td.ScoreDocs[0];
+			AreEqual(0.4619D, (double)d.Fields[0], 1E-4);
+			d = (FieldDoc)td.ScoreDocs[1];
+			AreEqual(1.0546D, (double)d.Fields[0], 1E-4);
+			d = (FieldDoc)td.ScoreDocs[2];
+			AreEqual(5.2842D, (double)d.Fields[0], 1E-4);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/TestExpressionRescorer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/TestExpressionRescorer.cs b/src/Lucene.Net.Tests.Expressions/TestExpressionRescorer.cs
new file mode 100644
index 0000000..301e6f9
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/TestExpressionRescorer.cs
@@ -0,0 +1,92 @@
+using Lucene.Net.Documents;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Store;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions
+{
+	public class TestExpressionRescorer : Lucene.Net.Util.LuceneTestCase
+	{
+		internal IndexSearcher searcher;
+
+		internal DirectoryReader reader;
+
+		internal Directory dir;
+
+		[SetUp]
+		public override void SetUp()
+		{
+			base.SetUp();
+			dir = NewDirectory();
+			var iw = new RandomIndexWriter(Random(), dir);
+			var doc = new Document
+			{
+			    NewStringField("id", "1", Field.Store.YES),
+			    NewTextField("body", "some contents and more contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 5)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "2", Field.Store.YES),
+			    NewTextField("body", "another document with different contents", Field.Store
+			        .NO),
+			    new NumericDocValuesField("popularity", 20)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "3", Field.Store.YES),
+			    NewTextField("body", "crappy contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 2)
+			};
+		    iw.AddDocument(doc);
+			reader = iw.Reader;
+			searcher = new IndexSearcher(reader);
+			iw.Dispose();
+		}
+
+		[TearDown]
+		public override void TearDown()
+		{
+			reader.Dispose();
+			dir.Dispose();
+			base.TearDown();
+		}
+
+		[Test]
+		public virtual void TestBasic()
+		{
+			// create a sort field and sort by it (reverse order)
+			Query query = new TermQuery(new Term("body", "contents"));
+			IndexReader r = searcher.IndexReader;
+			// Just first pass query
+			TopDocs hits = searcher.Search(query, 10);
+			AreEqual(3, hits.TotalHits);
+			AreEqual("3", r.Document(hits.ScoreDocs[0].Doc).Get("id"));
+			AreEqual("1", r.Document(hits.ScoreDocs[1].Doc).Get("id"));
+			AreEqual("2", r.Document(hits.ScoreDocs[2].Doc).Get("id"));
+			// Now, rescore:
+			Expression e = JavascriptCompiler.Compile("sqrt(_score) + ln(popularity)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("popularity", SortField.Type_e.INT));
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			Rescorer rescorer = e.GetRescorer(bindings);
+			hits = rescorer.Rescore(searcher, hits, 10);
+			AreEqual(3, hits.TotalHits);
+			AreEqual("2", r.Document(hits.ScoreDocs[0].Doc).Get("id"));
+			AreEqual("1", r.Document(hits.ScoreDocs[1].Doc).Get("id"));
+			AreEqual("3", r.Document(hits.ScoreDocs[2].Doc).Get("id"));
+			string expl = rescorer.Explain(searcher, searcher.Explain(query, hits.ScoreDocs[0].Doc), hits.ScoreDocs[0].Doc).ToString();
+			// Confirm the explanation breaks out the individual
+			// variables:
+			IsTrue(expl.Contains("= variable \"popularity\""));
+			// Confirm the explanation includes first pass details:
+			IsTrue(expl.Contains("= first pass score"));
+			IsTrue(expl.Contains("body:contents in"));
+		}
+	}
+}


Mime
View raw message