How To: Serialize your DataTable to Silverlight using WCF service

Friday, January 22, 2010 by Vladimir Enchev | Comments 32

Did you know that you can serialize any DataTable to Silverlight easily from your custom WCF service in very few lines of code?

[OperationContract]
public IEnumerable<Dictionary<string, object>> GetData()
{
    var table = YourDataTable;

    var columns = table.Columns.Cast<DataColumn>();

    return table.AsEnumerable().Select(r => columns.Select(c =>
                         new { Column = c.ColumnName, Value = r[c] })
                     .ToDictionary(i => i.Column, i => i.Value != DBNull.Value ? i.Value : null));
}

 

I’ve made small update for my lightweight DataTable for Silverlight and now you can create the table directly from IEnumerable<Dictionary<string, object>>:

namespace Telerik.Data
{
    public class DataTable : IEnumerable
    {
        public DataTable(IEnumerable<Dictionary<string, object>> source)
        {
            ...
}
    }
}

Now you can use all these to serialize any DataTable with unknown number of columns and types to the Silverlight client and bind desired control:

XAML
<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
    xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView">
    <Grid x:Name="LayoutRoot">
        <telerik:RadGridView x:Name="RadGridView1" />
    </Grid>
</UserControl>



C#

using System.Windows.Controls;
using SilverlightApplication1.ServiceReference1;
using Telerik.Data;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            var client = new MyServiceClient();
            client.GetDataCompleted += (s,e) => 
            {
                RadGridView1.ItemsSource = new DataTable(e.Result);
            };

            client.GetDataAsync("SELECT CustomerID, CompanyName, ContactName, City, Country, Address, Fax FROM Customers");
        }
    }
}


The result - fully functional dynamic DataGrid and DataTable:
 image

Enjoy!

 

32 Comments

  • Aurélien Dubosson 13 Apr 2010
    Hi Vlad,

    In your former post Lightweight Data Table for your Silverlight applications, you say we can use Dynamic Linq.

    If I understand I can on server side create my own datatable comprising all data of a database and return it with a webservice to the client.

    Have you got an example how to use Dynamic Linq with a datatable ? With that can we create our own query to display data into Rad GridView ? 

  • Aurélien Dubosson 13 Apr 2010
    Hi Vlad,

    In your former post Lightweight Data Table for your Silverlight applications, you say we can use Dynamic Linq.

    If I understand I can on server side create my own datatable comprising all data of a database and return it with a webservice to the client.

    Have you got an example how to use Dynamic Linq with a datatable ? With that can we create our own query to display data into Rad GridView ? 

  • Vlad 14 Apr 2010
    Hi Aurélien,

    Indeed in the first version of my DataTable I've used Dynamic LINQ library however we've changed this and now you do not need Dynamic LINQ.
    The idea of this post was to show how to convert and serialize any server-side DataTable to IEnumerable<Dictionary<string, object>> and how to populate our own DataTable client-side with this data.

    Vlad
  • Aurélien Dubosson 14 Apr 2010
    Hi Vlad,

    I try to change the sql query just with SELECT CustomerID FROM Customers I always have the same result with all columns.

    I'm beginner with C# I don't understand the following sentence, what means (s,e)  => ?
    client.GetDataCompleted += (s,e) => 
    
    Thanks for your previous response.
    
    Aurélien
  • Varsha Motwani 19 May 2010
    Please tell me how to save the data after changes in the grid back to db
  • Vlad 19 May 2010
    You will need additional method for your service where you can post desired changes - for example the grid Items collection.
  • Ali Wieckowicz 27 May 2010

    Love this solution!

     

    Maybe you have some suggestions.  I have a stored procedure that returns an undefined number of tables and I’m trying to wrap my head around how I might be able to modify this solution in such a way to allow the service to return multiple tables as single response.   Can I serialize the dataset or table collection in a similar way, or do I have to build an object?

    Thanks,

    Ali W

  • Kevin McBrearty 10 Jun 2010
    I love this solution and have been using it in a project that I am developing.  I have a couple of questions though. 

    1.  I am currently trying to use this with a RadChart and define a ChartSortDescriptor.  I get an error message stating at least one object must implement IComparable.  I believe that this doesn't work because the dictionary class doesn't implement IComparable but we also don't have the SortedDictionary class available to us.  Are you aware of any way to get this to work?

    2.  The Web Service that I am using is written in VB.Net.  Do you know how to convert the following line to VB so that I can simplify how I am sending the data from the web service to the silverlight client?

     

     

    return table.AsEnumerable().Select(r => columns.Select(c =>

     

     

     

    new { Column = c.ColumnName, Value = r[c] })

     

    .ToDictionary(i => i.Column, i => i.Value !=

     

    DBNull.Value ? i.Value : null));

     

  • Kevin McBrearty 14 Jun 2010
    I as able to rework the code for the Web Service to vb.NET.  The code is below for anyone else who might need it.

        Public Function GetData(ByVal Query As String) As IEnumerable(Of Dictionary(Of String, Object)) Implements IEKService.GetData  
            Dim table As DataTable = GetDataTable(query)  
            Dim columns = table.Columns.Cast(Of DataColumn)()  
     
            Return table.AsEnumerable.Select(Function(r) columns.Select(Function(c) New With { _  
                  .Column = c.ColumnName, _  
                  .Value = r(c) _  
            }).ToDictionary(Function(i) i.Column, Function(i) If(i.Value Is DBNull.Value, Nothing, i.Value)))  
        End Function 

    Also I had to make a slight modification to the constructor of the class to not throw an error when the first value of a column is null.  I am sure there is more elegant way to code this but it works.

            public DataTable(IEnumerable<Dictionary<string, object>> source)  
            {  
                if (source != null)  
                {  
                    var firstItem = source.FirstOrDefault();  
     
                    if (firstItem != null)  
                    {  
                        foreach (var key in firstItem)  
                        {  
                            if (key.Value == null)  
                            {  
                                Columns.Add(new DataColumn() { ColumnName = key.Key, DataType = typeof(string) });  
                            }  
                            else  
                            {  
                                Columns.Add(new DataColumn() { ColumnName = key.Key, DataType = key.Value.GetType() });  
                            }                          
                        }  
     
                        foreach (var item in source)  
                        {  
                            var row = new DataRow();  
     
                            foreach (var key in item)  
                            {  
                                row[key.Key] = key.Value;  
                            }  
                            Rows.Add(row);  
                        }  
                    }  
                }  
            } 

    I am still looking at a way to get the sorting for the RadChart to work when using this Datatable.
  • Jim 02 Aug 2010
    Anybody know how to get this C# to work in VB?  I have everything else working. 

                var client = new MyServiceClient(); 
                client.GetDataCompleted += (s,e) =>  
                { 
                    RadGridView1.ItemsSource = new DataTable(e.Result); 
                }; 
     

     Tried adding an event handler, but can't cast the e.result to a datatable.

        Dim client = New dynamicDataClient 
            AddHandler client.GetDataCompleted, AddressOf dynamicDataCompleted 
     
    .... 
     
        Private Sub dynamicDataCompleted(ByVal sender As Object, ByVal e As GetDataCompletedEventArgs) 
     
            dataGrid.ItemsSource = New DataTable(e.results) 
        End Sub 
     
  • Atilla 12 Aug 2010
    Hi, dear Vlad

    my SQL query 20 columns and 12 rows record but not load DataGrid.. Database records return, but not load Datagrid.. I don't understand? Please help me.

    Thans Atilla.
  • Sam 06 Oct 2010
    I can't get the return statement to compile in VB.net.  This is what I am using (copied from above), but I am getting an overload resolution failed error.

    Return table.AsEnumerable.Select(Function(r) columns.Select(Function(c) New With { _
                  .Column = c.ColumnName, _
                  .Value = r(c) _
            }).ToDictionary(Function(i) i.Column, Function(i) If(i.Value Is DBNull.Value, Nothing, i.Value)))
  • Vlad 07 Oct 2010
     Here is the VB.NET version of the service:
    Public Class MyService 
            <OperationContract> 
            Public Function GetData(ByVal query As StringAs IEnumerable(Of Dictionary(Of StringObject)) 
                Dim table = GetDataTable(query) 
     
                Dim columns = table.Columns.Cast(Of DataColumn)() 
     
                Return table.AsEnumerable().Select(Function(r) columns.Select(Function(c) New With {Key .Column = c.ColumnName, Key .Value = r(c)}).ToDictionary(Function(i) i.Column, Function(i)If(i.Value IsNot DBNull.Value, i.Value, Nothing))) 
            End Function 
     
            Public Function GetDataTable(ByVal query As StringAs DataTable 
                Dim connString = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString 
                Dim conn = New SqlConnection(connString) 
                Dim adapter = New SqlDataAdapter() 
                adapter.SelectCommand = New SqlCommand(query, conn) 
     
                Dim table = New DataTable() 
     
                conn.Open() 
                Try 
                    adapter.Fill(table) 
                Finally 
                    conn.Close() 
                End Try 
     
                Return table 
            End Function 
        End Class 
  • Sam 07 Oct 2010
    Sorry to be so annoying, but now I am having some issues on the client side converting the client side data table to vb.net.  I am using your example in the Lightweight data table for Silverlight.  Have you converted that anywhere?
    Thanks,
    Sam
  • Sam Bronchetti 12 Oct 2010
    Vlad,

    In your latest serialization application, when I convert Dynamic.cs to VB.NET, there are a lot of compiler issues.  It also affects other portions of my application (like app.xaml won't compile any more).  Any thoughts?
  • Sam Bronchetti 12 Oct 2010
    1     Private queryable As IQueryable = Nothing 
    2         Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator  
    3             If queryable Is Nothing Then  
    4                 Dim type = ClassFactory.Instance.GetDynamicClass(Me.Columns.[Select](Function(c) New DynamicProperty(c.ColumnName, c.DataType)))  
    5                 Dim propertyInfos = type.GetProperties().ToList()  
    6  
    7                 Dim mylist = DirectCast(Activator.CreateInstance(GetType(List(Of )).MakeGenericType(type)), IList)  
    8                 For Each row In Me.Rows  
    9                     Dim item = Activator.CreateInstance(type)  
    10                     propertyInfos.ForEach(Function(p) p.SetValue(item, row(p.Name), Nothing))  
    11                     mylist.Add(item)  
    12                 Next  
    13  
    14                 queryable = mylist.AsQueryable()  
    15             End If  
    16  
    17             Return queryable.GetEnumerator()  
    18         End Function 
    I have converted just about all of the application.  The error I am getting now is on line 10 above.  The error I am getting is "Expression does not produce a value" (compiler error). I have the rest of DataTable.cs and Dynamic.cs converted to VB.  Any help on that last lambda expression would be greatly appreciated.
  • Hıncal 13 Oct 2010
    Hi Vlad,

    I think there is a small problem with your DataTable in VS2010. I'm trying to use it to bind RadChart, but if I bind a date column in DateTime type then axis don't autostepping labels and everyting mixes. If I use OADate as double then everything works fine but tooltip formatting. So I stucked.. You may see my posts in telerik forums:

    http://www.telerik.com/community/forums/silverlight/chart/radchart-axisx-label-autostep-misfunctionality.aspx
    http://www.telerik.com/community/forums/silverlight/chart/oadate-support-in-tooltips.aspx

    Although in VS2008 with DateTime type works flawlessly..
  • rc 13 Oct 2010
    Hi,

    I tried the code and it generally works. but when it is already returning a large set (1400 rows with about 10 columns), it gives out an error.
  • Sam 13 Oct 2010
    RC,

    I had something similar occur, but it is not an issue with the RadGridView or Vlad's Datatable, it is with the web service you might be calling.  In the web.config, I had to add something that looked like the following:
            <behaviors> 
                <serviceBehaviors> 
                    <behavior name="slPartnerCare.Web.Service1Behavior">  
                        <serviceMetadata httpGetEnabled="true"/>  
                        <serviceDebug includeExceptionDetailInFaults="true"/>  
                        <dataContractSerializer maxItemsInObjectGraph="2147483646"/>  
                    </behavior> 
                </serviceBehaviors> 
            </behaviors> 
     
    The key was the dataContractSerializer.
  • Sam 13 Oct 2010
    ''Copyright (C) Microsoft Corporation.  All rights reserved.  
     
    Imports System.Collections.Generic  
    Imports System.Text  
    Imports System.Linq  
    Imports System.Linq.Expressions  
    Imports System.Reflection  
    Imports System.Reflection.Emit  
    Imports System.Threading  
    Imports System.Dynamic  
    Imports System.Runtime.CompilerServices  
     
    Namespace SQLWiz.Dynamic  
        Module DynamicQueryable  
            Sub New()  
            End Sub  
            <Extension()> _  
            Public Function Where(Of T)(ByVal source As IQueryable(Of T), ByVal predicate As String, ByVal ParamArray values As Object()) As IQueryable(Of T)  
                Return DirectCast(Where(DirectCast(source, IQueryable), predicate, values), IQueryable(Of T))  
            End Function  
     
            <Extension()> _  
            Public Function Where(ByVal source As IQueryable, ByVal predicate As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If predicate Is Nothing Then  
                    Throw New ArgumentNullException("predicate")  
                End If  
                Dim lambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, GetType(Boolean), predicate, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Where", New Type() {source.ElementType}, source.Expression, Expression.Quote(lambda)))  
            End Function  
     
            <Extension()> _  
            Public Function [Select](ByVal source As IQueryable, ByVal selector As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If selector Is Nothing Then  
                    Throw New ArgumentNullException("selector")  
                End If  
                Dim lambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, selector, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Select", New Type() {source.ElementType, lambda.Body.Type}, source.Expression, Expression.Quote(lambda)))  
            End Function  
     
            <Extension()> _  
            Public Function OrderBy(Of T)(ByVal source As IQueryable(Of T), ByVal ordering As String, ByVal ParamArray values As Object()) As IQueryable(Of T)  
                Return DirectCast(OrderBy(DirectCast(source, IQueryable), ordering, values), IQueryable(Of T))  
            End Function  
     
            <Extension()> _  
            Public Function OrderBy(ByVal source As IQueryable, ByVal ordering As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If ordering Is Nothing Then  
                    Throw New ArgumentNullException("ordering")  
                End If  
                Dim parameters As ParameterExpression() = New ParameterExpression() {Expression.Parameter(source.ElementType, "")}  
                Dim parser As New ExpressionParser(parameters, ordering, values)  
                Dim orderings As IEnumerable(Of DynamicOrdering) = parser.ParseOrdering()  
                Dim queryExpr As Expression = source.Expression  
                Dim methodAsc As String = "OrderBy" 
                Dim methodDesc As String = "OrderByDescending" 
                For Each o As DynamicOrdering In orderings  
                    queryExpr = Expression.[Call](GetType(Queryable), If(o.Ascending, methodAsc, methodDesc), New Type() {source.ElementType, o.Selector.Type}, queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)))  
                    methodAsc = "ThenBy" 
                    methodDesc = "ThenByDescending" 
                Next  
                Return source.Provider.CreateQuery(queryExpr)  
            End Function  
     
            <Extension()> _  
            Public Function Take(ByVal source As IQueryable, ByVal count As Integer) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Take", New Type() {source.ElementType}, source.Expression, Expression.Constant(count)))  
            End Function  
     
            <Extension()> _  
            Public Function Skip(ByVal source As IQueryable, ByVal count As Integer) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Skip", New Type() {source.ElementType}, source.Expression, Expression.Constant(count)))  
            End Function  
     
            <Extension()> _  
            Public Function GroupBy(ByVal source As IQueryable, ByVal keySelector As String, ByVal elementSelector As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If keySelector Is Nothing Then  
                    Throw New ArgumentNullException("keySelector")  
                End If  
                If elementSelector Is Nothing Then  
                    Throw New ArgumentNullException("elementSelector")  
                End If  
                Dim keyLambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, keySelector, values)  
                Dim elementLambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, elementSelector, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "GroupBy", New Type() {source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type}, source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda)))  
            End Function  
     
            <Extension()> _  
            Public Function Any(ByVal source As IQueryable) As Boolean  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return CBool(source.Provider.Execute(Expression.[Call](GetType(Queryable), "Any", New Type() {source.ElementType}, source.Expression)))  
            End Function  
     
            <Extension()> _  
            Public Function Count(ByVal source As IQueryable) As Integer  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return CInt(source.Provider.Execute(Expression.[Call](GetType(Queryable), "Count", New Type() {source.ElementType}, source.Expression)))  
            End Function  
        End Module  
     
        Public MustInherit Class DynamicClass  
            Public Overrides Function ToString() As String  
                Dim props As PropertyInfo() = Me.[GetType]().GetProperties(BindingFlags.Instance Or BindingFlags.[Public])  
                Dim sb As New StringBuilder()  
                sb.Append("{")  
                For i As Integer = 0 To props.Length - 1  
                    If i > 0 Then  
                        sb.Append(", ")  
                    End If  
                    sb.Append(props(i).Name)  
                    sb.Append("=")  
                    sb.Append(props(i).GetValue(Me, Nothing))  
                Next  
                sb.Append("}")  
                Return sb.ToString()  
            End Function  
        End Class  
     
        Public Class DynamicProperty  
            Private m_name As String  
            Private m_type As Type  
     
            Public Sub New(ByVal name As String, ByVal type As Type)  
                If name Is Nothing Then  
                    Throw New ArgumentNullException("name")  
                End If  
                If type Is Nothing Then  
                    Throw New ArgumentNullException("type")  
                End If  
                Me.m_name = name  
                Me.m_type = type  
            End Sub  
     
            Public ReadOnly Property Name() As String  
                Get  
                    Return m_name  
                End Get  
            End Property  
     
            Public ReadOnly Property Type() As Type  
                Get  
                    Return m_type  
                End Get  
            End Property  
        End Class  
     
        Module DynamicExpression  
            Sub New()  
            End Sub  
            Public Function Parse(ByVal resultType As Type, ByVal expression As String, ByVal ParamArray values As Object()) As Expression  
                Dim parser As New ExpressionParser(Nothing, expression, values)  
                Return parser.Parse(resultType)  
            End Function  
     
            Public Function ParseLambda(ByVal itType As Type, ByVal resultType As Type, ByVal expression__1 As String, ByVal ParamArray values As Object()) As LambdaExpression  
                Return ParseLambda(New ParameterExpression() {Expression.Parameter(itType, "")}, resultType, expression__1, values)  
            End Function  
     
            Public Function ParseLambda(ByVal parameters As ParameterExpression(), ByVal resultType As Type, ByVal expression__1 As String, ByVal ParamArray values As Object()) As LambdaExpression  
                Dim parser As New ExpressionParser(parameters, expression__1, values)  
                Return Expression.Lambda(parser.Parse(resultType), parameters)  
            End Function  
     
            Public Function ParseLambda(Of T, S)(ByVal expression As String, ByVal ParamArray values As Object()) As Expression(Of Func(Of T, S))  
                Return DirectCast(ParseLambda(GetType(T), GetType(S), expression, values), Expression(Of Func(Of T, S)))  
            End Function  
     
            Public Function CreateClass(ByVal ParamArray properties As DynamicProperty()) As Type  
                Return ClassFactory.Instance.GetDynamicClass(properties)  
            End Function  
     
            Public Function CreateClass(ByVal properties As IEnumerable(Of DynamicProperty)) As Type  
                Return ClassFactory.Instance.GetDynamicClass(properties)  
            End Function  
        End Module  
     
        Friend Class DynamicOrdering  
            Public Selector As Expression  
            Public Ascending As Boolean  
        End Class  
     
        Friend Class Signature  
            Implements IEquatable(Of Signature)  
            Public properties As DynamicProperty()  
            Public hashCode As Integer  
     
            Public Sub New(ByVal properties As IEnumerable(Of DynamicProperty))  
                Me.properties = properties.ToArray()  
                hashCode = 0 
                For Each p As DynamicProperty In properties  
                    hashCodehashCode = hashCode Xor p.Name.GetHashCode() Xor p.Type.GetHashCode()  
                Next  
            End Sub  
     
            Public Overrides Function GetHashCode() As Integer  
                Return hashCode  
            End Function  
     
            Public Overrides Function Equals(ByVal obj As Object) As Boolean  
                Return If(TypeOf obj Is Signature, Equals(DirectCast(obj, Signature)), False)  
            End Function  
     
            Public Overloads Function Equals(ByVal other As Signature) As Boolean Implements IEquatable(Of Signature).Equals  
                If properties.Length <> other.properties.Length Then  
                    Return False  
                End If  
                For i As Integer = 0 To properties.Length - 1  
                    If properties(i).Name <> other.properties(i).Name OrElse properties(i).Type IsNot other.properties(i).Type Then  
                        Return False  
                    End If  
                Next  
                Return True  
            End Function  
        End Class  
     
        Friend Class ClassFactory  
            Public Shared ReadOnly Instance As New ClassFactory()  
     
            Shared Sub New()  
            End Sub  
            ' Trigger lazy initialization of static fields  
            Private [module] As ModuleBuilder  
            Private classes As Dictionary(Of Signature, Type)  
            Private classCount As Integer  
     
            Private Sub New()  
                Dim name As New AssemblyName("DynamicClasses")  
                Dim assembly As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run)  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                    New ReflectionPermission(PermissionState.Unrestricted).Assert()  
    #End If  
                Try  
                    [module] = assembly.DefineDynamicModule("Module")  
                Finally  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                    PermissionSet.RevertAssert()  
    #End If  
                End Try  
                classes = New Dictionary(Of Signature, Type)()  
            End Sub  
     
            Public Function GetDynamicClass(ByVal properties As IEnumerable(Of DynamicProperty)) As Type  
                Try  
                    Dim signature As New Signature(properties)  
                    Dim type As Type  
                    If Not classes.TryGetValue(signature, type) Then  
                        type = CreateDynamicClass(signature.properties)  
                        classes.Add(signature, type)  
                    End If  
                    Return type  
                Finally  
                End Try  
            End Function  
     
            Private Function CreateDynamicClass(ByVal properties As DynamicProperty()) As Type  
                Try  
                    Dim typeName As String = "DynamicClass" & (classCount + 1)  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                        New ReflectionPermission(PermissionState.Unrestricted).Assert()  
    #End If  
                    Try  
                        Dim tb As TypeBuilder = Me.[module].DefineType(typeName, TypeAttributes.[Class] Or TypeAttributes.[Public], GetType(DynamicClass))  
                        Dim fields As FieldInfo() = GenerateProperties(tb, properties)  
                        GenerateEquals(tb, fields)  
                        GenerateGetHashCode(tb, fields)  
                        Dim result As Type = tb.CreateType()  
                        classCount += 1  
                        Return result  
                    Finally  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                        PermissionSet.RevertAssert()  
    #End If  
                    End Try  
                Finally  
                End Try  
            End Function  
     
            Private Function GenerateProperties(ByVal tb As TypeBuilder, ByVal properties As DynamicProperty()) As FieldInfo()  
                Dim fields As FieldInfo() = New FieldBuilder(properties.Length - 1) {}  
                For i As Integer = 0 To properties.Length - 1  
                    Dim dp As DynamicProperty = properties(i)  
                    Dim fb As FieldBuilder = tb.DefineField("_" & dp.Name, dp.Type, FieldAttributes.[Private])  
                    Dim pb As PropertyBuilder = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, Nothing)  
                    Dim mbGet As MethodBuilder = tb.DefineMethod("get_" & dp.Name, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, dp.Type, Type.EmptyTypes)  
                    Dim genGet As ILGenerator = mbGet.GetILGenerator()  
                    genGet.Emit(OpCodes.Ldarg_0)  
                    genGet.Emit(OpCodes.Ldfld, fb)  
                    genGet.Emit(OpCodes.Ret)  
                    Dim mbSet As MethodBuilder = tb.DefineMethod("set_" & dp.Name, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, Nothing, New Type() {dp.Type})  
                    Dim genSet As ILGenerator = mbSet.GetILGenerator()  
                    genSet.Emit(OpCodes.Ldarg_0)  
                    genSet.Emit(OpCodes.Ldarg_1)  
                    genSet.Emit(OpCodes.Stfld, fb)  
                    genSet.Emit(OpCodes.Ret)  
                    pb.SetGetMethod(mbGet)  
                    pb.SetSetMethod(mbSet)  
                    fields(i) = fb  
                Next  
                Return fields  
            End Function  
     
            Private Sub GenerateEquals(ByVal tb As TypeBuilder, ByVal fields As FieldInfo())  
                Dim mb As MethodBuilder = tb.DefineMethod("Equals", MethodAttributes.[Public] Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig, GetType(Boolean), New Type() {GetType(Object)})  
                Dim gen As ILGenerator = mb.GetILGenerator()  
                Dim other As LocalBuilder = gen.DeclareLocal(tb)  
                Dim [next] As Label = gen.DefineLabel()  
                gen.Emit(OpCodes.Ldarg_1)  
                gen.Emit(OpCodes.Isinst, tb)  
                gen.Emit(OpCodes.Stloc, other)  
                gen.Emit(OpCodes.Ldloc, other)  
                gen.Emit(OpCodes.Brtrue_S, [next])  
                gen.Emit(OpCodes.Ldc_I4_0)  
                gen.Emit(OpCodes.Ret)  
                gen.MarkLabel([next])  
                For Each field As FieldInfo In fields  
                    Dim ft As Type = field.FieldType  
                    Dim ct As Type = GetType(EqualityComparer(Of )).MakeGenericType(ft)  
                    [next] = gen.DefineLabel()  
                    gen.EmitCall(OpCodes.[Call], ct.GetMethod("get_Default"), Nothing)  
                    gen.Emit(OpCodes.Ldarg_0)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.Emit(OpCodes.Ldloc, other)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", New Type() {ft, ft}), Nothing)  
                    gen.Emit(OpCodes.Brtrue_S, [next])  
                    gen.Emit(OpCodes.Ldc_I4_0)  
                    gen.Emit(OpCodes.Ret)  
                    gen.MarkLabel([next])  
                Next  
                gen.Emit(OpCodes.Ldc_I4_1)  
                gen.Emit(OpCodes.Ret)  
            End Sub  
     
            Private Sub GenerateGetHashCode(ByVal tb As TypeBuilder, ByVal fields As FieldInfo())  
                Dim mb As MethodBuilder = tb.DefineMethod("GetHashCode", MethodAttributes.[Public] Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig, GetType(Integer), Type.EmptyTypes)  
                Dim gen As ILGenerator = mb.GetILGenerator()  
                gen.Emit(OpCodes.Ldc_I4_0)  
                For Each field As FieldInfo In fields  
                    Dim ft As Type = field.FieldType  
                    Dim ct As Type = GetType(EqualityComparer(Of )).MakeGenericType(ft)  
                    gen.EmitCall(OpCodes.[Call], ct.GetMethod("get_Default"), Nothing)  
                    gen.Emit(OpCodes.Ldarg_0)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", New Type() {ft}), Nothing)  
                    gen.Emit(OpCodes.[Xor])  
                Next  
                gen.Emit(OpCodes.Ret)  
            End Sub  
        End Class  
     
        Public NotInheritable Class ParseException  
            Inherits Exception  
            Private m_position As Integer  
     
            Public Sub New(ByVal message As String, ByVal position As Integer)  
                MyBase.New(message)  
                Me.m_position = position  
            End Sub  
     
            Public ReadOnly Property Position() As Integer  
                Get  
                    Return m_position  
                End Get  
            End Property  
     
            Public Overrides Function ToString() As String  
                Return String.Format(Res.ParseExceptionFormat, Message, m_position)  
            End Function  
        End Class  
     
        Friend Class ExpressionParser  
            Private Structure myToken  
                Public id As TokenId  
                Public text As String  
                Public pos As Integer  
            End Structure  
     
            Private Enum TokenId  
                Unknown  
                [End]  
                Identifier  
                StringLiteral  
                IntegerLiteral  
                RealLiteral  
                Exclamation  
                Percent  
                Amphersand  
                OpenParen  
                CloseParen  
                Asterisk  
                Plus  
                Comma  
                Minus  
                Dot  
                Slash  
                Colon  
                LessThan  
                Equal  
                GreaterThan  
                Question  
                OpenBracket  
                CloseBracket  
                Bar  
                ExclamationEqual  
                DoubleAmphersand  
                LessThanEqual  
                LessGreater  
                DoubleEqual  
                GreaterThanEqual  
                DoubleBar  
            End Enum  
     
            Private Interface ILogicalSignatures  
                Sub F(ByVal x As Boolean, ByVal y As Boolean)  
                Sub F(ByVal x As Global.System.Nullable(Of Boolean), ByVal y As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IArithmeticSignatures  
                Sub F(ByVal x As Integer, ByVal y As Integer)  
                Sub F(ByVal x As UInteger, ByVal y As UInteger)  
                Sub F(ByVal x As Long, ByVal y As Long)  
                Sub F(ByVal x As ULong, ByVal y As ULong)  
                Sub F(ByVal x As Single, ByVal y As Single)  
                Sub F(ByVal x As Double, ByVal y As Double)  
                Sub F(ByVal x As Decimal, ByVal y As Decimal)  
                Sub F(ByVal x As Global.System.Nullable(Of Integer), ByVal y As Global.System.Nullable(Of Integer))  
                Sub F(ByVal x As Global.System.Nullable(Of UInteger), ByVal y As Global.System.Nullable(Of UInteger))  
                Sub F(ByVal x As Global.System.Nullable(Of Long), ByVal y As Global.System.Nullable(Of Long))  
                Sub F(ByVal x As Global.System.Nullable(Of ULong), ByVal y As Global.System.Nullable(Of ULong))  
                Sub F(ByVal x As Global.System.Nullable(Of Single), ByVal y As Global.System.Nullable(Of Single))  
                Sub F(ByVal x As Global.System.Nullable(Of Double), ByVal y As Global.System.Nullable(Of Double))  
                Sub F(ByVal x As Global.System.Nullable(Of Decimal), ByVal y As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Private Interface IRelationalSignatures  
                Inherits IArithmeticSignatures  
                Overloads Sub F(ByVal x As String, ByVal y As String)  
                Overloads Sub F(ByVal x As Char, ByVal y As Char)  
                Overloads Sub F(ByVal x As DateTime, ByVal y As DateTime)  
                Overloads Sub F(ByVal x As TimeSpan, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of Char), ByVal y As Global.System.Nullable(Of Char))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of DateTime))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of TimeSpan), ByVal y As Global.System.Nullable(Of TimeSpan))  
            End Interface  
     
            Private Interface IEqualitySignatures  
                Inherits IRelationalSignatures  
                Overloads Sub F(ByVal x As Boolean, ByVal y As Boolean)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of Boolean), ByVal y As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IAddSignatures  
                Inherits IArithmeticSignatures  
                Overloads Sub F(ByVal x As DateTime, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As TimeSpan, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of TimeSpan))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of TimeSpan), ByVal y As Global.System.Nullable(Of TimeSpan))  
            End Interface  
     
            Private Interface ISubtractSignatures  
                Inherits IAddSignatures  
                Overloads Sub F(ByVal x As DateTime, ByVal y As DateTime)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of DateTime))  
            End Interface  
     
            Private Interface INegationSignatures  
                Sub F(ByVal x As Integer)  
                Sub F(ByVal x As Long)  
                Sub F(ByVal x As Single)  
                Sub F(ByVal x As Double)  
                Sub F(ByVal x As Decimal)  
                Sub F(ByVal x As Global.System.Nullable(Of Integer))  
                Sub F(ByVal x As Global.System.Nullable(Of Long))  
                Sub F(ByVal x As Global.System.Nullable(Of Single))  
                Sub F(ByVal x As Global.System.Nullable(Of Double))  
                Sub F(ByVal x As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Private Interface INotSignatures  
                Sub F(ByVal x As Boolean)  
                Sub F(ByVal x As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IEnumerableSignatures  
                Sub Where(ByVal predicate As Boolean)  
                Sub Any()  
                Sub Any(ByVal predicate As Boolean)  
                Sub All(ByVal predicate As Boolean)  
                Sub Count()  
                Sub Count(ByVal predicate As Boolean)  
                Sub Min(ByVal selector As Object)  
                Sub Max(ByVal selector As Object)  
                Sub Sum(ByVal selector As Integer)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Integer))  
                Sub Sum(ByVal selector As Long)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Long))  
                Sub Sum(ByVal selector As Single)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Single))  
                Sub Sum(ByVal selector As Double)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Double))  
                Sub Sum(ByVal selector As Decimal)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Decimal))  
                Sub Average(ByVal selector As Integer)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Integer))  
                Sub Average(ByVal selector As Long)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Long))  
                Sub Average(ByVal selector As Single)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Single))  
                Sub Average(ByVal selector As Double)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Double))  
                Sub Average(ByVal selector As Decimal)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Shared ReadOnly predefinedTypes As Type() = {GetType([Object]), GetType([Boolean]), GetType([Char]), GetType([String]), GetType([SByte]), GetType([Byte]), _  
             GetType(Int16), GetType(UInt16), GetType(Int32), GetType(UInt32), GetType(Int64), GetType(UInt64), _  
             GetType([Single]), GetType([Double]), GetType([Decimal]), GetType(DateTime), GetType(TimeSpan), GetType(Guid), _  
             GetType(Math), GetType(Convert)}  
     
            Shared ReadOnly trueLiteral As ExpressionExpression = Expression.Constant(True)  
            Shared ReadOnly falseLiteral As ExpressionExpression = Expression.Constant(False)  
            Shared ReadOnly nullLiteral As ExpressionExpression = Expression.Constant(Nothing)  
     
            Shared ReadOnly keywordIt As String = "it" 
            Shared ReadOnly keywordIif As String = "iif" 
            Shared ReadOnly keywordNew As String = "new" 
     
            Shared keywords As Dictionary(Of String, Object)  
     
            Private symbols As Dictionary(Of String, Object)  
            Private externals As IDictionary(Of String, Object)  
            Private literals As Dictionary(Of Expression, String)  
            Private it As ParameterExpression  
            Private text As String  
            Private textPos As Integer  
            Private textLen As Integer  
            Private ch As Char  
            Private varToken As myToken  
     
            Public Sub New(ByVal parameters As ParameterExpression(), ByVal expression As String, ByVal values As Object())  
                If expression Is Nothing Then  
                    Throw New ArgumentNullException("expression")  
                End If  
                If keywords Is Nothing Then  
                    keywords = CreateKeywords()  
                End If  
                symbols = New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)  
                literals = New Dictionary(Of Expression, String)()  
                If parameters IsNot Nothing Then  
                    ProcessParameters(parameters)  
                End If  
                If values IsNot Nothing Then  
                    ProcessValues(values)  
                End If  
                text = expression 
                texttextLen = text.Length  
                SetTextPos(0)  
                NextToken()  
            End Sub  
     
            Private Sub ProcessParameters(ByVal parameters As ParameterExpression())  
                For Each pe As ParameterExpression In parameters  
                    If Not [String].IsNullOrEmpty(pe.Name) Then  
                        AddSymbol(pe.Name, pe)  
                    End If  
                Next  
                If parameters.Length = 1 AndAlso [String].IsNullOrEmpty(parameters(0).Name) Then  
                    it = parameters(0)  
                End If  
            End Sub  
     
            Private Sub ProcessValues(ByVal values As Object())  
                For i As Integer = 0 To values.Length - 1  
                    Dim value As Object = values(i)  
                    If i = values.Length - 1 AndAlso TypeOf value Is IDictionary(Of String, Object) Then  
                        externals = DirectCast(value, IDictionary(Of String, Object))  
                    Else  
                        AddSymbol("@" & i.ToString(Globalization.CultureInfo.InvariantCulture), value)  
                    End If  
                Next  
            End Sub  
     
            Private Sub AddSymbol(ByVal name As String, ByVal value As Object)  
                If symbols.ContainsKey(name) Then  
                    Throw ParseError(Res.DuplicateIdentifier, name)  
                End If  
                symbols.Add(name, value)  
            End Sub  
     
            Public Function Parse(ByVal resultType As Type) As Expression  
                Dim exprPos As Integer = varToken.pos  
                Dim expr As Expression = ParseExpression()  
                If resultType IsNot Nothing Then  
                    If (InlineAssignHelper(expr, PromoteExpression(expr, resultType, True))) Is Nothing Then  
                        Throw ParseError(exprPos, Res.ExpressionTypeMismatch, GetTypeName(resultType))  
                    End If  
                End If  
                ValidateToken(TokenId.[End], Res.SyntaxError)  
                Return expr  
            End Function  
     
            '#Pragma warning disable 0219  
            Public Function ParseOrdering() As IEnumerable(Of DynamicOrdering)  
                Dim orderings As New List(Of DynamicOrdering)()  
                While True  
                    Dim expr As Expression = ParseExpression()  
                    Dim ascending As Boolean = True 
                    If TokenIdentifierIs("asc") OrElse TokenIdentifierIs("ascending") Then  
                        NextToken()  
                    ElseIf TokenIdentifierIs("desc") OrElse TokenIdentifierIs("descending") Then  
                        NextToken()  
                        ascending = False 
                    End If  
                    orderings.Add(New DynamicOrdering() With { _  
                      .Selector = expr, _  
                      .Ascending = ascending _  
                    })  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                ValidateToken(TokenId.[End], Res.SyntaxError)  
                Return orderings  
            End Function  
            '#Pragma warning restore 0219  
     
            ' ?: operator  
            Private Function ParseExpression() As Expression  
                Dim errorPos As Integer = varToken.pos  
                Dim expr As Expression = ParseLogicalOr()  
                If varToken.id = TokenId.Question Then  
                    NextToken()  
                    Dim expr1 As Expression = ParseExpression()  
                    ValidateToken(TokenId.Colon, Res.ColonExpected)  
                    NextToken()  
                    Dim expr2 As Expression = ParseExpression()  
                    expr = GenerateConditional(expr, expr1, expr2, errorPos)  
                End If  
                Return expr  
            End Function  
     
            ' ||, or operator  
            Private Function ParseLogicalOr() As Expression  
                Dim left As Expression = ParseLogicalAnd()  
                While varToken.id = TokenId.DoubleBar OrElse TokenIdentifierIs("or")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseLogicalAnd()  
                    CheckAndPromoteOperands(GetType(ILogicalSignatures), op.text, left, right, op.pos)  
                    left = Expression.[OrElse](left, right)  
                End While  
                Return left  
            End Function  
     
            ' &&, and operator  
            Private Function ParseLogicalAnd() As Expression  
                Dim left As Expression = ParseComparison()  
                While varToken.id = TokenId.DoubleAmphersand OrElse TokenIdentifierIs("and")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseComparison()  
                    CheckAndPromoteOperands(GetType(ILogicalSignatures), op.text, left, right, op.pos)  
                    left = Expression.[AndAlso](left, right)  
                End While  
                Return left  
            End Function  
     
            ' =, ==, !=, <>, >>=, <<= operators  
            Private Function ParseComparison() As Expression  
                Dim left As Expression = ParseAdditive()  
                While varToken.id = TokenId.Equal OrElse varToken.id = TokenId.DoubleEqual OrElse varToken.id = TokenId.ExclamationEqual OrElse varToken.id = TokenId.LessGreater OrElse varToken.id = TokenId.GreaterThan OrElse varToken.id = TokenId.GreaterThanEqual OrElse varToken.id = TokenId.LessThan OrElse varToken.id = TokenId.LessThanEqual  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseAdditive()  
                    Dim isEquality As Boolean = op.id = TokenId.Equal OrElse op.id = TokenId.DoubleEqual OrElse op.id = TokenId.ExclamationEqual OrElse op.id = TokenId.LessGreater  
                    If isEquality AndAlso Not left.Type.IsValueType AndAlso Not right.Type.IsValueType Then  
                        If Not left.Type.Equals(right.Type) Then  
                            If left.Type.IsAssignableFrom(right.Type) Then  
                                right = Expression.Convert(right, left.Type)  
                            ElseIf right.Type.IsAssignableFrom(left.Type) Then  
                                left = Expression.Convert(left, right.Type)  
                            Else  
                                Throw IncompatibleOperandsError(op.text, left, right, op.pos)  
                            End If  
                        End If  
                    ElseIf IsEnumType(left.Type) OrElse IsEnumType(right.Type) Then  
                        If Not left.Type.Equals(right.Type) Then  
                            Dim e As Expression  
                            If (InlineAssignHelper(e, PromoteExpression(right, left.Type, True))) IsNot Nothing Then  
                                right = e 
                            ElseIf (InlineAssignHelper(e, PromoteExpression(left, right.Type, True))) IsNot Nothing Then  
                                left = e  
                            Else  
                                Throw IncompatibleOperandsError(op.text, left, right, op.pos)  
                            End If  
                        End If  
                    Else  
                        CheckAndPromoteOperands(If(isEquality, GetType(IEqualitySignatures), GetType(IRelationalSignatures)), op.text, left, right, op.pos)  
                    End If  
                    Select Case op.id  
                        Case TokenId.Equal, TokenId.DoubleEqual  
                            left = GenerateEqual(left, right)  
                            Exit Select  
                        Case TokenId.ExclamationEqual, TokenId.LessGreater  
                            left = GenerateNotEqual(left, right)  
                            Exit Select  
                        Case TokenId.GreaterThan  
                            left = GenerateGreaterThan(left, right)  
                            Exit Select  
                        Case TokenId.GreaterThanEqual  
                            left = GenerateGreaterThanEqual(left, right)  
                            Exit Select  
                        Case TokenId.LessThan  
                            left = GenerateLessThan(left, right)  
                            Exit Select  
                        Case TokenId.LessThanEqual  
                            left = GenerateLessThanEqual(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' +, -, & operators  
            Private Function ParseAdditive() As Expression  
                Dim left As Expression = ParseMultiplicative()  
                While varToken.id = TokenId.Plus OrElse varToken.id = TokenId.Minus OrElse varToken.id = TokenId.Amphersand  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseMultiplicative()  
                    Select Case op.id  
                        Case TokenId.Plus  
                            If left.Type.Equals(GetType(String)) OrElse right.Type.Equals(GetType(String)) Then  
                                left = GenerateStringConcat(left, right)  
                                Exit Select  
                            End If  
                            CheckAndPromoteOperands(GetType(IAddSignatures), op.text, left, right, op.pos)  
                            left = GenerateAdd(left, right)  
                            Exit Select  
                        Case TokenId.Minus  
                            CheckAndPromoteOperands(GetType(ISubtractSignatures), op.text, left, right, op.pos)  
                            left = GenerateSubtract(left, right)  
                            Exit Select  
                        Case TokenId.Amphersand  
                            left = GenerateStringConcat(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' *, /, %, mod operators  
            Private Function ParseMultiplicative() As Expression  
                Dim left As Expression = ParseUnary()  
                While varToken.id = TokenId.Asterisk OrElse varToken.id = TokenId.Slash OrElse varToken.id = TokenId.Percent OrElse TokenIdentifierIs("mod")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseUnary()  
                    CheckAndPromoteOperands(GetType(IArithmeticSignatures), op.text, left, right, op.pos)  
                    Select Case op.id  
                        Case TokenId.Asterisk  
                            left = Expression.Multiply(left, right)  
                            Exit Select  
                        Case TokenId.Slash  
                            left = Expression.Divide(left, right)  
                            Exit Select  
                        Case TokenId.Percent, TokenId.Identifier  
                            left = Expression.Modulo(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' -, !, not unary operators  
            Private Function ParseUnary() As Expression  
                If varToken.id = TokenId.Minus OrElse varToken.id = TokenId.Exclamation OrElse TokenIdentifierIs("not") Then  
                    Dim op As myToken = varToken 
                    NextToken()  
                    If op.id = TokenId.Minus AndAlso (varToken.id = TokenId.IntegerLiteral OrElse varToken.id = TokenId.RealLiteral) Then  
                        varToken.text = "-" & varToken.text  
                        varToken.pos = op.pos  
                        Return ParsePrimary()  
                    End If  
                    Dim expr As Expression = ParseUnary()  
                    If op.id = TokenId.Minus Then  
                        CheckAndPromoteOperand(GetType(INegationSignatures), op.text, expr, op.pos)  
                        expr = Expression.Negate(expr)  
                    Else  
                        CheckAndPromoteOperand(GetType(INotSignatures), op.text, expr, op.pos)  
                        expr = Expression.[Not](expr)  
                    End If  
                    Return expr  
                End If  
                Return ParsePrimary()  
            End Function  
     
            Private Function ParsePrimary() As Expression  
                Dim expr As Expression = ParsePrimaryStart()  
                While True  
                    If varToken.id = TokenId.Dot Then  
                        NextToken()  
                        expr = ParseMemberAccess(Nothing, expr)  
                    ElseIf varToken.id = TokenId.OpenBracket Then  
                        expr = ParseElementAccess(expr)  
                    Else  
                        Exit While  
                    End If  
                End While  
                Return expr  
            End Function  
     
            Private Function ParsePrimaryStart() As Expression  
                Select Case varToken.id  
                    Case TokenId.Identifier  
                        Return ParseIdentifier()  
                    Case TokenId.StringLiteral  
                        Return ParseStringLiteral()  
                    Case TokenId.IntegerLiteral  
                        Return ParseIntegerLiteral()  
                    Case TokenId.RealLiteral  
                        Return ParseRealLiteral()  
                    Case TokenId.OpenParen  
                        Return ParseParenExpression()  
                    Case Else  
                        Throw ParseError(Res.ExpressionExpected)  
                End Select  
            End Function  
     
            Private Function ParseStringLiteral() As Expression  
                ValidateToken(TokenId.StringLiteral)  
                Dim quote As Char = varToken.text(0)  
                Dim s As String = varToken.text.Substring(1, varToken.text.Length - 2)  
                Dim start As Integer = 0 
                While True  
                    Dim i As Integer = s.IndexOf(quote, start)  
                    If i < 0 Then  
                        Exit While  
                    End If  
                    ss = s.Remove(i, 1)  
                    start = i + 1  
                End While  
                If quote = "'"c Then  
                    If s.Length <> 1 Then  
                        Throw ParseError(Res.InvalidCharacterLiteral)  
                    End If  
                    NextToken()  
                    Return CreateLiteral(s(0), s)  
                End If  
                NextToken()  
                Return CreateLiteral(s, s)  
            End Function  
     
            Private Function ParseIntegerLiteral() As Expression  
                ValidateToken(TokenId.IntegerLiteral)  
                Dim text As String = varToken.text  
                If text(0) <> "-"c Then  
                    Dim value As ULong  
                    If Not UInt64.TryParse(text, value) Then  
                        Throw ParseError(Res.InvalidIntegerLiteral, text)  
                    End If  
                    NextToken()  
                    If value <= CULng(Int32.MaxValue) Then  
                        Return CreateLiteral(CInt(value), text)  
                    End If  
                    If value <= CULng(UInt32.MaxValue) Then  
                        Return CreateLiteral(CUInt(value), text)  
                    End If  
                    If value <= CULng(Int64.MaxValue) Then  
                        Return CreateLiteral(CLng(value), text)  
                    End If  
                    Return CreateLiteral(value, text)  
                Else  
                    Dim value As Long  
                    If Not Int64.TryParse(text, value) Then  
                        Throw ParseError(Res.InvalidIntegerLiteral, text)  
                    End If  
                    NextToken()  
                    If value >= Int32.MinValue AndAlso value <= Int32.MaxValue Then  
                        Return CreateLiteral(CInt(value), text)  
                    End If  
                    Return CreateLiteral(value, text)  
                End If  
            End Function  
     
            Private Function ParseRealLiteral() As Expression  
                ValidateToken(TokenId.RealLiteral)  
                Dim text As String = varToken.text  
                Dim value As Object = Nothing 
                Dim last As Char = text(text.Length - 1)  
                If last = "F"c OrElse last = "f"c Then  
                    Dim f As Single  
                    If [Single].TryParse(text.Substring(0, text.Length - 1), f) Then  
                        value = f 
                    End If  
                Else  
                    Dim d As Double  
                    If [Double].TryParse(text, d) Then  
                        value = d 
                    End If  
                End If  
                If value Is Nothing Then  
                    Throw ParseError(Res.InvalidRealLiteral, text)  
                End If  
                NextToken()  
                Return CreateLiteral(value, text)  
            End Function  
     
            Private Function CreateLiteral(ByVal value As Object, ByVal text As String) As Expression  
                Dim expr As ConstantExpression = Expression.Constant(value)  
                literals.Add(expr, text)  
                Return expr  
            End Function  
     
            Private Function ParseParenExpression() As Expression  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim e As Expression = ParseExpression()  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected)  
                NextToken()  
                Return e  
            End Function  
     
            Private Function ParseIdentifier() As Expression  
                ValidateToken(TokenId.Identifier)  
                Dim value As Object  
                If keywords.TryGetValue(varToken.text, value) Then  
                    If TypeOf value Is Type Then  
                        Return ParseTypeAccess(DirectCast(value, Type))  
                    End If  
                    If value Is DirectCast(keywordIt, Object) Then  
                        Return ParseIt()  
                    End If  
                    If value Is DirectCast(keywordIif, Object) Then  
                        Return ParseIif()  
                    End If  
                    If value Is DirectCast(keywordNew, Object) Then  
                        Return ParseNew()  
                    End If  
                    NextToken()  
                    Return DirectCast(value, Expression)  
                End If  
                If symbols.TryGetValue(varToken.text, value) OrElse externals IsNot Nothing AndAlso externals.TryGetValue(varToken.text, value) Then  
                    Dim expr As Expression = TryCast(value, Expression)  
                    If expr Is Nothing Then  
                        expr = Expression.Constant(value)  
                    Else  
                        Dim lambda As LambdaExpression = TryCast(expr, LambdaExpression)  
                        If lambda IsNot Nothing Then  
                            Return ParseLambdaInvocation(lambda)  
                        End If  
                    End If  
                    NextToken()  
                    Return expr  
                End If  
                If it IsNot Nothing Then  
                    Return ParseMemberAccess(Nothing, it)  
                End If  
                Throw ParseError(Res.UnknownIdentifier, varToken.text)  
            End Function  
     
            Private Function ParseIt() As Expression  
                If it Is Nothing Then  
                    Throw ParseError(Res.NoItInScope)  
                End If  
                NextToken()  
                Return it  
            End Function  
     
            Private Function ParseIif() As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                Dim args As Expression() = ParseArgumentList()  
                If args.Length <> 3 Then  
                    Throw ParseError(errorPos, Res.IifRequiresThreeArgs)  
                End If  
                Return GenerateConditional(args(0), args(1), args(2), errorPos)  
            End Function  
     
            Private Function GenerateConditional(ByVal test As Expression, ByVal expr1 As Expression, ByVal expr2 As Expression, ByVal errorPos As Integer) As Expression  
                If Not test.Type.Equals(GetType(Boolean)) Then  
                    Throw ParseError(errorPos, Res.FirstExprMustBeBool)  
                End If  
                If Not expr1.Type.Equals(expr2.Type) Then  
                    Dim expr1as2 As Expression = If(Not expr2.Equals(nullLiteral), PromoteExpression(expr1, expr2.Type, True), Nothing)  
                    Dim expr2as1 As Expression = If(Not expr2.Equals(nullLiteral), PromoteExpression(expr2, expr1.Type, True), Nothing)  
                    If expr1as2 IsNot Nothing AndAlso expr2as1 Is Nothing Then  
                        expr1 = expr1as2 
                    ElseIf expr2as1 IsNot Nothing AndAlso expr1as2 Is Nothing Then  
                        expr2 = expr2as1 
                    Else  
                        Dim type1 As String = If(Not expr2.Equals(nullLiteral), expr1.Type.Name, "null")  
                        Dim type2 As String = If(Not expr2.Equals(nullLiteral), expr2.Type.Name, "null")  
                        If expr1as2 IsNot Nothing AndAlso expr2as1 IsNot Nothing Then  
                            Throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2)  
                        End If  
                        Throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2)  
                    End If  
                End If  
                Return Expression.Condition(test, expr1, expr2)  
            End Function  
     
            Private Function ParseNew() As Expression  
                NextToken()  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim properties As New List(Of DynamicProperty)()  
                Dim expressions As New List(Of Expression)()  
                While True  
                    Dim exprPos As Integer = varToken.pos  
                    Dim expr As Expression = ParseExpression()  
                    Dim propName As String  
                    If TokenIdentifierIs("as") Then  
                        NextToken()  
                        propName = GetIdentifier()  
                        NextToken()  
                    Else  
                        Dim [me] As MemberExpression = TryCast(expr, MemberExpression)  
                        If [me] Is Nothing Then  
                            Throw ParseError(exprPos, Res.MissingAsClause)  
                        End If  
                        propName = [me].Member.Name  
                    End If  
                    expressions.Add(expr)  
                    properties.Add(New DynamicProperty(propName, expr.Type))  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)  
                NextToken()  
                Dim type As Type = DynamicExpression.CreateClass(properties)  
                Dim bindings As MemberBinding() = New MemberBinding(properties.Count - 1) {}  
                For i As Integer = 0 To bindings.Length - 1  
                    bindings(i) = Expression.Bind(type.GetProperty(properties(i).Name), expressions(i))  
                Next  
                Return Expression.MemberInit(Expression.[New](type), bindings)  
            End Function  
     
            Private Function ParseLambdaInvocation(ByVal lambda As LambdaExpression) As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                Dim args As Expression() = ParseArgumentList()  
                Dim method As MethodBase  
                If FindMethod(lambda.Type, "Invoke", False, args, method) <> 1 Then  
                    Throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda)  
                End If  
                Return Expression.Invoke(lambda, args)  
            End Function  
     
            Private Function ParseTypeAccess(ByVal type As Type) As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                If varToken.id = TokenId.Question Then  
                    If Not type.IsValueType OrElse IsNullableType(type) Then  
                        Throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type))  
                    End If  
                    type = GetType(Nullable(Of )).MakeGenericType(type)  
                    NextToken()  
                End If  
                If varToken.id = TokenId.OpenParen Then  
                    Dim args As Expression() = ParseArgumentList()  
                    Dim method As MethodBase  
                    Select Case FindBestMethod(type.GetConstructors(), args, method)  
                        Case 0  
                            If args.Length = 1 Then  
                                Return GenerateConversion(args(0), type, errorPos)  
                            End If  
                            Throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type))  
                        Case 1  
                            Return Expression.[New](DirectCast(method, ConstructorInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type))  
                    End Select  
                End If  
                ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected)  
                NextToken()  
                Return ParseMemberAccess(type, Nothing)  
            End Function  
     
            Private Function GenerateConversion(ByVal expr As Expression, ByVal type As Type, ByVal errorPos As Integer) As Expression  
                Dim exprType As Type = expr.Type  
                If exprType Is type Then  
                    Return expr  
                End If  
                If exprType.IsValueType AndAlso type.IsValueType Then  
                    If (IsNullableType(exprType) OrElse IsNullableType(type)) AndAlso GetNonNullableType(exprType) Is GetNonNullableType(type) Then  
                        Return Expression.Convert(expr, type)  
                    End If  
                    If (IsNumericType(exprType) OrElse IsEnumType(exprType)) AndAlso (IsNumericType(type)) OrElse IsEnumType(type) Then  
                        Return Expression.ConvertChecked(expr, type)  
                    End If  
                End If  
                If exprType.IsAssignableFrom(type) OrElse type.IsAssignableFrom(exprType) OrElse exprType.IsInterface OrElse type.IsInterface Then  
                    Return Expression.Convert(expr, type)  
                End If  
                Throw ParseError(errorPos, Res.CannotConvertValue, GetTypeName(exprType), GetTypeName(type))  
            End Function  
     
            Private Function ParseMemberAccess(ByVal type As Type, ByVal instance As Expression) As Expression  
                If instance IsNot Nothing Then  
                    type = instance.Type  
                End If  
                Dim errorPos As Integer = varToken.pos  
                Dim id As String = GetIdentifier()  
                NextToken()  
                If varToken.id = TokenId.OpenParen Then  
                    If instance IsNot Nothing AndAlso type IsNot GetType(String) Then  
                        Dim enumerableType As Type = FindGenericType(GetType(IEnumerable(Of )), type)  
                        If enumerableType IsNot Nothing Then  
                            Dim elementType As Type = enumerableType.GetGenericArguments()(0)  
                            Return ParseAggregate(instance, elementType, id, errorPos)  
                        End If  
                    End If  
                    Dim args As Expression() = ParseArgumentList()  
                    Dim mb As MethodBase  
                    Select Case FindMethod(type, id, instance Is Nothing, args, mb)  
                        Case 0  
                            Throw ParseError(errorPos, Res.NoApplicableMethod, id, GetTypeName(type))  
                        Case 1  
                            Dim method As MethodInfo = DirectCast(mb, MethodInfo)  
                            If Not IsPredefinedType(method.DeclaringType) Then  
                                Throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType))  
                            End If  
                            If method.ReturnType Is GetType(Void) Then  
                                Throw ParseError(errorPos, Res.MethodIsVoid, id, GetTypeName(method.DeclaringType))  
                            End If  
                            Return Expression.[Call](instance, DirectCast(method, MethodInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousMethodInvocation, id, GetTypeName(type))  
                    End Select  
                Else  
                    Dim member As MemberInfo = FindPropertyOrField(type, id, instance Is Nothing)  
                    If member Is Nothing Then  
                        Throw ParseError(errorPos, Res.UnknownPropertyOrField, id, GetTypeName(type))  
                    End If  
                    Return If(TypeOf member Is PropertyInfo, Expression.[Property](instance, DirectCast(member, PropertyInfo)), Expression.Field(instance, DirectCast(member, FieldInfo)))  
                End If  
            End Function  
     
            Private Shared Function FindGenericType(ByVal generic As Type, ByVal type As Type) As Type  
                While type IsNot Nothing AndAlso type IsNot GetType(Object)  
                    If type.IsGenericType AndAlso type.GetGenericTypeDefinition() Is generic Then  
                        Return type  
                    End If  
                    If generic.IsInterface Then  
                        For Each intfType As Type In type.GetInterfaces()  
                            Dim found As Type = FindGenericType(generic, intfType)  
                            If found IsNot Nothing Then  
                                Return found  
                            End If  
                        Next  
                    End If  
                    typetype = type.BaseType  
                End While  
                Return Nothing  
            End Function  
     
            Private Function ParseAggregate(ByVal instance As Expression, ByVal elementType As Type, ByVal methodName As String, ByVal errorPos As Integer) As Expression  
                Dim outerIt As ParameterExpression = it 
                Dim innerIt As ParameterExpression = Expression.Parameter(elementType, "")  
                it = innerIt 
                Dim args As Expression() = ParseArgumentList()  
                it = outerIt 
                Dim signature As MethodBase  
                If FindMethod(GetType(IEnumerableSignatures), methodName, False, args, signature) <> 1 Then  
                    Throw ParseError(errorPos, Res.NoApplicableAggregate, methodName)  
                End If  
                Dim typeArgs As Type()  
                If signature.Name = "Min" OrElse signature.Name = "Max" Then  
                    typeArgs = New Type() {elementType, args(0).Type}  
                Else  
                    typeArgs = New Type() {elementType}  
                End If  
                If args.Length = 0 Then  
                    args = New Expression() {instance}  
                Else  
                    args = New Expression() {instance, Expression.Lambda(args(0), innerIt)}  
                End If  
                Return Expression.[Call](GetType(Enumerable), signature.Name, typeArgs, args)  
            End Function  
     
            Private Function ParseArgumentList() As Expression()  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim args As Expression() = If(varToken.id <> TokenId.CloseParen, ParseArguments(), New Expression(-1) {})  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)  
                NextToken()  
                Return args  
            End Function  
     
            Private Function ParseArguments() As Expression()  
                Dim argList As New List(Of Expression)()  
                While True  
                    argList.Add(ParseExpression())  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                Return argList.ToArray()  
            End Function  
     
            Private Function ParseElementAccess(ByVal expr As Expression) As Expression  
                Dim errorPos As Integer = varToken.pos  
                ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected)  
                NextToken()  
                Dim args As Expression() = ParseArguments()  
                ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected)  
                NextToken()  
                If expr.Type.IsArray Then  
                    If expr.Type.GetArrayRank() <> 1 OrElse args.Length <> 1 Then  
                        Throw ParseError(errorPos, Res.CannotIndexMultiDimArray)  
                    End If  
                    Dim index As Expression = PromoteExpression(args(0), GetType(Integer), True)  
                    If index Is Nothing Then  
                        Throw ParseError(errorPos, Res.InvalidIndex)  
                    End If  
                    Return Expression.ArrayIndex(expr, index)  
                Else  
                    Dim mb As MethodBase  
                    Select Case FindIndexer(expr.Type, args, mb)  
                        Case 0  
                            Throw ParseError(errorPos, Res.NoApplicableIndexer, GetTypeName(expr.Type))  
                        Case 1  
                            Return Expression.[Call](expr, DirectCast(mb, MethodInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousIndexerInvocation, GetTypeName(expr.Type))  
                    End Select  
                End If  
            End Function  
     
            Private Shared Function IsPredefinedType(ByVal type As Type) As Boolean  
                For Each t As Type In predefinedTypes  
                    If t Is type Then  
                        Return True  
                    End If  
                Next  
                Return False  
            End Function  
     
            Private Shared Function IsNullableType(ByVal type As Type) As Boolean  
                Return type.IsGenericType AndAlso type.GetGenericTypeDefinition() Is GetType(Nullable(Of ))  
            End Function  
     
            Private Shared Function GetNonNullableType(ByVal type As Type) As Type  
                Return If(IsNullableType(type), type.GetGenericArguments()(0), type)  
            End Function  
     
            Private Shared Function GetTypeName(ByVal type As Type) As String  
                Dim baseType As Type = GetNonNullableType(type)  
                Dim s As String = baseType.Name  
                If type IsNot baseType Then  
                    s += "?"c  
                End If  
                Return s  
            End Function  
     
            Private Shared Function IsNumericType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) <> 0  
            End Function  
     
            Private Shared Function IsSignedIntegralType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) = 2  
            End Function  
     
            Private Shared Function IsUnsignedIntegralType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) = 3  
            End Function  
     
            Private Shared Function GetNumericTypeKind(ByVal type__1 As Type) As Integer  
                type__1 = GetNonNullableType(type__1)  
                If type__1.IsEnum Then  
                    Return 0  
                End If  
                Select Case Type.GetTypeCode(type__1)  
                    Case TypeCode.[Char], TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                        Return 1  
                    Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64  
                        Return 2  
                    Case TypeCode.[Byte], TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64  
                        Return 3  
                    Case Else  
                        Return 0  
                End Select  
            End Function  
     
            Private Shared Function IsEnumType(ByVal type As Type) As Boolean  
                Return GetNonNullableType(type).IsEnum  
            End Function  
     
            Private Sub CheckAndPromoteOperand(ByVal signatures As Type, ByVal opName As String, ByRef expr As Expression, ByVal errorPos As Integer)  
                Dim args As Expression() = New Expression() {expr}  
                Dim method As MethodBase  
                If FindMethod(signatures, "F", False, args, method) <> 1 Then  
                    Throw ParseError(errorPos, Res.IncompatibleOperand, opName, GetTypeName(args(0).Type))  
                End If  
                expr = args(0)  
            End Sub  
     
            Private Sub CheckAndPromoteOperands(ByVal signatures As Type, ByVal opName As String, ByRef left As Expression, ByRef right As Expression, ByVal errorPos As Integer)  
                Dim args As Expression() = New Expression() {left, right}  
                Dim method As MethodBase  
                If FindMethod(signatures, "F", False, args, method) <> 1 Then  
                    Throw IncompatibleOperandsError(opName, left, right, errorPos)  
                End If  
                left = args(0)  
                right = args(1)  
            End Sub  
     
            Private Function IncompatibleOperandsError(ByVal opName As String, ByVal left As Expression, ByVal right As Expression, ByVal pos As Integer) As Exception  
                Return ParseError(pos, Res.IncompatibleOperands, opName, GetTypeName(left.Type), GetTypeName(right.Type))  
            End Function  
     
            Private Function FindPropertyOrField(ByVal type__1 As Type, ByVal memberName As String, ByVal staticAccess As Boolean) As MemberInfo  
                Dim flags As BindingFlagsBindingFlags = BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or (If(staticAccess, BindingFlags.[Static], BindingFlags.Instance))  
                For Each t As Type In SelfAndBaseTypes(type__1)  
                    Dim members As MemberInfo() = t.FindMembers(MemberTypes.[Property] Or MemberTypes.Field, flags, Type.FilterNameIgnoreCase, memberName)  
                    If members.Length <> 0 Then  
                        Return members(0)  
                    End If  
                Next  
                Return Nothing  
            End Function  
     
            Private Function FindMethod(ByVal type__1 As Type, ByVal methodName As String, ByVal staticAccess As Boolean, ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                Dim flags As BindingFlagsBindingFlags = BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or (If(staticAccess, BindingFlags.[Static], BindingFlags.Instance))  
                For Each t As Type In SelfAndBaseTypes(type__1)  
                    Dim members As MemberInfo() = t.FindMembers(MemberTypes.Method, flags, Type.FilterNameIgnoreCase, methodName)  
                    Dim count As Integer = FindBestMethod(members.Cast(Of MethodBase)(), args, method)  
                    If count <> 0 Then  
                        Return count  
                    End If  
                Next  
                method = Nothing 
                Return 0  
            End Function  
     
            Private Function FindIndexer(ByVal type As Type, ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                For Each t As Type In SelfAndBaseTypes(type)  
                    Dim members As MemberInfo() = t.GetDefaultMembers()  
                    If members.Length <> 0 Then  
                        Dim methods As IEnumerable(Of MethodBase) = members.OfType(Of PropertyInfo)().[Select](Function(p) DirectCast(p.GetGetMethod(), MethodBase)).Where(Function(m) m IsNot Nothing)  
                        Dim count As Integer = FindBestMethod(methods, args, method)  
                        If count <> 0 Then  
                            Return count  
                        End If  
                    End If  
                Next  
                method = Nothing 
                Return 0  
            End Function  
     
            Private Shared Function SelfAndBaseTypes(ByVal type As Type) As IEnumerable(Of Type)  
                If type.IsInterface Then  
                    Dim types As New List(Of Type)()  
                    AddInterface(types, type)  
                    Return types  
                End If  
                Return SelfAndBaseClasses(type)  
            End Function  
     
            Private Shared Function SelfAndBaseClasses(ByVal type As Type) As IEnumerable(Of Type)  
                While type IsNot Nothing  
                    Return New Type() {type}  
                    typetype = type.BaseType  
                End While  
            End Function  
     
            Private Shared Sub AddInterface(ByVal types As List(Of Type), ByVal type As Type)  
                If Not types.Contains(type) Then  
                    types.Add(type)  
                    For Each t As Type In type.GetInterfaces()  
                        AddInterface(types, t)  
                    Next  
                End If  
            End Sub  
     
            Private Class MethodData  
                Public MethodBase As MethodBase  
                Public Parameters As ParameterInfo()  
                Public Args As Expression()  
            End Class  
     
            Private Function FindBestMethod(ByVal methods As IEnumerable(Of MethodBase), ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                Dim applicable As MethodData() = methods.[Select](Function(m) New MethodData() With { _  
                  .MethodBase = m, _  
                  .Parameters = m.GetParameters() _  
                }).Where(Function(m) IsApplicable(m, args)).ToArray()  
                If applicable.Length > 1 Then  
                    applicableapplicable = applicable.Where(Function(m) applicable.All(Function(n) m.Equals(n) OrElse IsBetterThan(args, m, n))).ToArray()  
                End If  
                If applicable.Length = 1 Then  
                    Dim md As MethodData = applicable(0)  
                    For i As Integer = 0 To args.Length - 1  
                        args(i) = md.Args(i)  
                    Next  
                    method = md.MethodBase  
                Else  
                    method = Nothing 
                End If  
                Return applicable.Length  
            End Function  
     
            Private Function IsApplicable(ByVal method As MethodData, ByVal args As Expression()) As Boolean  
                If method.Parameters.Length <> args.Length Then  
                    Return False  
                End If  
                Dim promotedArgs As Expression() = New Expression(args.Length - 1) {}  
                For i As Integer = 0 To args.Length - 1  
                    Dim pi As ParameterInfo = method.Parameters(i)  
                    If pi.IsOut Then  
                        Return False  
                    End If  
                    Dim promoted As Expression = PromoteExpression(args(i), pi.ParameterType, False)  
                    If promoted Is Nothing Then  
                        Return False  
                    End If  
                    promotedArgs(i) = promoted  
                Next  
                method.Args = promotedArgs 
                Return True  
            End Function  
     
            Private Function PromoteExpression(ByVal expr As Expression, ByVal type__1 As Type, ByVal exact As Boolean) As Expression  
                If expr.Type.Equals(type__1) Then  
                    Return expr  
                End If  
                If TypeOf expr Is ConstantExpression Then  
                    Dim ce As ConstantExpression = DirectCast(expr, ConstantExpression)  
                    If ce.Equals(nullLiteral) Then  
                        If Not type__1.IsValueType OrElse IsNullableType(type__1) Then  
                            Return Expression.Constant(Nothing, type__1)  
                        End If  
                    Else  
                        Dim text As String  
                        If literals.TryGetValue(ce, text) Then  
                            Dim target As Type = GetNonNullableType(type__1)  
                            Dim value As [Object] = Nothing  
                            Select Case Type.GetTypeCode(ce.Type)  
                                Case TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64  
                                    value = ParseNumber(text, target)  
                                    Exit Select  
                                Case TypeCode.[Double]  
                                    If target Is GetType(Decimal) Then  
                                        value = ParseNumber(text, target)  
                                    End If  
                                    Exit Select  
                                Case TypeCode.[String]  
                                    value = ParseEnum(text, target)  
                                    Exit Select  
                            End Select  
                            If value IsNot Nothing Then  
                                Return Expression.Constant(value, type__1)  
                            End If  
                        End If  
                    End If  
                End If  
                If IsCompatibleWith(expr.Type, type__1) Then  
                    If type__1.IsValueType OrElse exact Then  
                        Return Expression.Convert(expr, type__1)  
                    End If  
                    Return expr  
                End If  
                Return Nothing  
            End Function  
     
            Private Shared Function ParseNumber(ByVal text As String, ByVal type__1 As Type) As Object  
                Select Case Type.GetTypeCode(GetNonNullableType(type__1))  
                    Case TypeCode.[SByte]  
                        Dim sb As SByte  
                        If SByte.TryParse(text, sb) Then  
                            Return sb  
                        End If  
                        Exit Select  
                    Case TypeCode.[Byte]  
                        Dim b As Byte  
                        If Byte.TryParse(text, b) Then  
                            Return b  
                        End If  
                        Exit Select  
                    Case TypeCode.Int16  
                        Dim s As Short  
                        If Short.TryParse(text, s) Then  
                            Return s  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt16  
                        Dim us As UShort  
                        If UShort.TryParse(text, us) Then  
                            Return us  
                        End If  
                        Exit Select  
                    Case TypeCode.Int32  
                        Dim i As Integer  
                        If Integer.TryParse(text, i) Then  
                            Return i  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt32  
                        Dim ui As UInteger  
                        If UInteger.TryParse(text, ui) Then  
                            Return ui  
                        End If  
                        Exit Select  
                    Case TypeCode.Int64  
                        Dim l As Long  
                        If Long.TryParse(text, l) Then  
                            Return l  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt64  
                        Dim ul As ULong  
                        If ULong.TryParse(text, ul) Then  
                            Return ul  
                        End If  
                        Exit Select  
                    Case TypeCode.[Single]  
                        Dim f As Single  
                        If Single.TryParse(text, f) Then  
                            Return f  
                        End If  
                        Exit Select  
                    Case TypeCode.[Double]  
                        Dim d As Double  
                        If Double.TryParse(text, d) Then  
                            Return d  
                        End If  
                        Exit Select  
                    Case TypeCode.[Decimal]  
                        Dim e As Decimal  
                        If Decimal.TryParse(text, e) Then  
                            Return e  
                        End If  
                        Exit Select  
                End Select  
                Return Nothing  
            End Function  
     
            Private Shared Function ParseEnum(ByVal name As String, ByVal type__1 As Type) As Object  
                If type__1.IsEnum Then  
                    Dim memberInfos As MemberInfo() = type__1.FindMembers(MemberTypes.Field, BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or BindingFlags.[Static], Type.FilterNameIgnoreCase, name)  
                    If memberInfos.Length <> 0 Then  
                        Return DirectCast(memberInfos(0), FieldInfo).GetValue(Nothing)  
                    End If  
                End If  
                Return Nothing  
            End Function  
     
            Private Shared Function IsCompatibleWith(ByVal source As Type, ByVal target As Type) As Boolean  
                If source Is target Then  
                    Return True  
                End If  
                If Not target.IsValueType Then  
                    Return target.IsAssignableFrom(source)  
                End If  
                Dim st As Type = GetNonNullableType(source)  
                Dim tt As Type = GetNonNullableType(target)  
                If st IsNot source AndAlso tt Is target Then  
                    Return False  
                End If  
                Dim sc As TypeCode = If(st.IsEnum, TypeCode.[Object], Type.GetTypeCode(st))  
                Dim tc As TypeCode = If(tt.IsEnum, TypeCode.[Object], Type.GetTypeCode(tt))  
                Select Case sc  
                    Case TypeCode.[SByte]  
                        Select Case tc  
                            Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], _  
                             TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.[Byte]  
                        Select Case tc  
                            Case TypeCode.[Byte], TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, _  
                             TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int16  
                        Select Case tc  
                            Case TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt16  
                        Select Case tc  
                            Case TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.[Single], _  
                             TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int32  
                        Select Case tc  
                            Case TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt32  
                        Select Case tc  
                            Case TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int64  
                        Select Case tc  
                            Case TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt64  
                        Select Case tc  
                            Case TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.[Single]  
                        Select Case tc  
                            Case TypeCode.[Single], TypeCode.[Double]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case Else  
                        If st Is tt Then  
                            Return True  
                        End If  
                        Exit Select  
                End Select  
                Return False  
            End Function  
     
            Private Shared Function IsBetterThan(ByVal args As Expression(), ByVal m1 As MethodData, ByVal m2 As MethodData) As Boolean  
                Dim better As Boolean = False 
                For i As Integer = 0 To args.Length - 1  
                    Dim c As Integer = CompareConversions(args(i).Type, m1.Parameters(i).ParameterType, m2.Parameters(i).ParameterType)  
                    If c < 0 Then  
                        Return False  
                    End If  
                    If c > 0 Then  
                        better = True 
                    End If  
                Next  
                Return better  
            End Function  
     
            ' Return 1 if s -> t1 is a better conversion than s -> t2  
            ' Return -1 if s -> t2 is a better conversion than s -> t1  
            ' Return 0 if neither conversion is better  
            Private Shared Function CompareConversions(ByVal s As Type, ByVal t1 As Type, ByVal t2 As Type) As Integer  
                If t1 Is t2 Then  
                    Return 0  
                End If  
                If s Is t1 Then  
                    Return 1  
                End If  
                If s Is t2 Then  
                    Return -1  
                End If  
                Dim t1t2 As Boolean = IsCompatibleWith(t1, t2)  
                Dim t2t1 As Boolean = IsCompatibleWith(t2, t1)  
                If t1t2 AndAlso Not t2t1 Then  
                    Return 1  
                End If  
                If t2t1 AndAlso Not t1t2 Then  
                    Return -1  
                End If  
                If IsSignedIntegralType(t1) AndAlso IsUnsignedIntegralType(t2) Then  
                    Return 1  
                End If  
                If IsSignedIntegralType(t2) AndAlso IsUnsignedIntegralType(t1) Then  
                    Return -1  
                End If  
                Return 0  
            End Function  
     
            Private Function GenerateEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.Equal(left, right)  
            End Function  
     
            Private Function GenerateNotEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.NotEqual(left, right)  
            End Function  
     
            Private Function GenerateGreaterThan(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.GreaterThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.GreaterThan(left, right)  
            End Function  
     
            Private Function GenerateGreaterThanEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.GreaterThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.GreaterThanOrEqual(left, right)  
            End Function  
     
            Private Function GenerateLessThan(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.LessThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.LessThan(left, right)  
            End Function  
     
            Private Function GenerateLessThanEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.LessThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.LessThanOrEqual(left, right)  
            End Function  
     
            Private Function GenerateAdd(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) AndAlso right.Type.Equals(GetType(String)) Then  
                    Return GenerateStaticMethodCall("Concat", left, right)  
                End If  
                Return Expression.Add(left, right)  
            End Function  
     
            Private Function GenerateSubtract(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.Subtract(left, right)  
            End Function  
     
            Private Function GenerateStringConcat(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.[Call](Nothing, GetType(String).GetMethod("Concat", New Object() {GetType(Object), GetType(Object)}), New Object() {left, right})  
            End Function  
     
            Private Function GetStaticMethod(ByVal methodName As String, ByVal left As Expression, ByVal right As Expression) As MethodInfo  
                Return left.Type.GetMethod(methodName, New Object() {left.Type, right.Type})  
            End Function  
     
            Private Function GenerateStaticMethodCall(ByVal methodName As String, ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.[Call](Nothing, GetStaticMethod(methodName, left, right), New Object() {left, right})  
            End Function  
     
            Private Sub SetTextPos(ByVal pos As Integer)  
                textPos = pos 
                ch = If(textPos < textLen, text(textPos), ControlChars.NullChar)  
            End Sub  
     
            Private Sub NextChar()  
                If textPos < textLen Then  
                    textPos += 1  
                End If  
                ch = If(textPos < textLen, text(textPos), ControlChars.NullChar)  
            End Sub  
     
            Private Sub NextToken()  
                While [Char].IsWhiteSpace(ch)  
                    NextChar()  
                End While  
                Dim t As TokenId  
                Dim tokenPos As Integer = textPos 
                Select Case ch  
                    Case "!"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.ExclamationEqual  
                        Else  
                            t = TokenId.Exclamation  
                        End If  
                        Exit Select  
                    Case "%"c  
                        NextChar()  
                        t = TokenId.Percent  
                        Exit Select  
                    Case "&"c  
                        NextChar()  
                        If cch = "&"c Then  
                            NextChar()  
                            t = TokenId.DoubleAmphersand  
                        Else  
                            t = TokenId.Amphersand  
                        End If  
                        Exit Select  
                    Case "("c  
                        NextChar()  
                        t = TokenId.OpenParen  
                        Exit Select  
                    Case ")"c  
                        NextChar()  
                        t = TokenId.CloseParen  
                        Exit Select  
                    Case "*"c  
                        NextChar()  
                        t = TokenId.Asterisk  
                        Exit Select  
                    Case "+"c  
                        NextChar()  
                        t = TokenId.Plus  
                        Exit Select  
                    Case ","c  
                        NextChar()  
                        t = TokenId.Comma  
                        Exit Select  
                    Case "-"c  
                        NextChar()  
                        t = TokenId.Minus  
                        Exit Select  
                    Case "."c  
                        NextChar()  
                        t = TokenId.Dot  
                        Exit Select  
                    Case "/"c  
                        NextChar()  
                        t = TokenId.Slash  
                        Exit Select  
                    Case ":"c  
                        NextChar()  
                        t = TokenId.Colon  
                        Exit Select  
                    Case "<"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.LessThanEqual  
                        ElseIf cch = ">"c Then  
                            NextChar()  
                            t = TokenId.LessGreater  
                        Else  
                            t = TokenId.LessThan  
                        End If  
                        Exit Select  
                    Case "="c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.DoubleEqual  
                        Else  
                            t = TokenId.Equal  
                        End If  
                        Exit Select  
                    Case ">"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.GreaterThanEqual  
                        Else  
                            t = TokenId.GreaterThan  
                        End If  
                        Exit Select  
                    Case "?"c  
                        NextChar()  
                        t = TokenId.Question  
                        Exit Select  
                    Case "["c  
                        NextChar()  
                        t = TokenId.OpenBracket  
                        Exit Select  
                    Case "]"c  
                        NextChar()  
                        t = TokenId.CloseBracket  
                        Exit Select  
                    Case "|"c  
                        NextChar()  
                        If cch = "|"c Then  
                            NextChar()  
                            t = TokenId.DoubleBar  
                        Else  
                            t = TokenId.Bar  
                        End If  
                        Exit Select  
                    Case """"c, "'"c  
                        Dim quote As Char = ch 
                        Do  
                            NextChar()  
                            While textPos < textLen AndAlso ch <> quote  
                                NextChar()  
                            End While  
                            If textPos = textLen Then  
                                Throw ParseError(textPos, Res.UnterminatedStringLiteral)  
                            End If  
                            NextChar()  
                        Loop While ch = quote 
                        t = TokenId.StringLiteral  
                        Exit Select  
                    Case Else  
                        If [Char].IsLetter(ch) OrElse cch = "@"c OrElse cch = "_"c Then  
                            Do  
                                NextChar()  
                            Loop While [Char].IsLetterOrDigit(ch) OrElse cch = "_"c  
                            t = TokenId.Identifier  
                            Exit Select  
                        End If  
                        If [Char].IsDigit(ch) Then  
                            t = TokenId.IntegerLiteral  
                            Do  
                                NextChar()  
                            Loop While [Char].IsDigit(ch)  
                            If cch = "."c Then  
                                t = TokenId.RealLiteral  
                                NextChar()  
                                ValidateDigit()  
                                Do  
                                    NextChar()  
                                Loop While [Char].IsDigit(ch)  
                            End If  
                            If cch = "E"c OrElse cch = "e"c Then  
                                t = TokenId.RealLiteral  
                                NextChar()  
                                If cch = "+"c OrElse cch = "-"c Then  
                                    NextChar()  
                                End If  
                                ValidateDigit()  
                                Do  
                                    NextChar()  
                                Loop While [Char].IsDigit(ch)  
                            End If  
                            If cch = "F"c OrElse cch = "f"c Then  
                                NextChar()  
                            End If  
                            Exit Select  
                        End If  
                        If textPos = textLen Then  
                            t = TokenId.[End]  
                            Exit Select  
                        End If  
                        Throw ParseError(textPos, Res.InvalidCharacter, ch)  
                End Select  
                varToken.id = t 
                varToken.text = text.Substring(tokenPos, textPos - tokenPos)  
                varToken.pos = tokenPos 
            End Sub  
     
            Private Function TokenIdentifierIs(ByVal id As String) As Boolean  
                Return varToken.id = TokenId.Identifier AndAlso [String].Equals(id, varToken.text, StringComparison.OrdinalIgnoreCase)  
            End Function  
     
            Private Function GetIdentifier() As String  
                ValidateToken(TokenId.Identifier, Res.IdentifierExpected)  
                Dim id As String = varToken.text  
                If id.Length > 1 AndAlso id(0) = "@"c Then  
                    idid = id.Substring(1)  
                End If  
                Return id  
            End Function  
     
            Private Sub ValidateDigit()  
                If Not [Char].IsDigit(ch) Then  
                    Throw ParseError(textPos, Res.DigitExpected)  
                End If  
            End Sub  
     
            Private Sub ValidateToken(ByVal t As TokenId, ByVal errorMessage As String)  
                If varToken.id <> t Then  
                    Throw ParseError(errorMessage)  
                End If  
            End Sub  
     
            Private Sub ValidateToken(ByVal t As TokenId)  
                If varToken.id <> t Then  
                    Throw ParseError(Res.SyntaxError)  
                End If  
            End Sub  
     
            Private Function ParseError(ByVal format As String, ByVal ParamArray args As Object()) As Exception  
                Return ParseError(varToken.pos, format, args)  
            End Function  
     
            Private Function ParseError(ByVal pos As Integer, ByVal format As String, ByVal ParamArray args As Object()) As Exception  
                Return New ParseException(String.Format(Globalization.CultureInfo.CurrentCulture, format, args), pos)  
            End Function  
     
            Private Shared Function CreateKeywords() As Dictionary(Of String, Object)  
                Dim d As New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)  
                d.Add("true", trueLiteral)  
                d.Add("false", falseLiteral)  
                d.Add("null", nullLiteral)  
                d.Add(keywordIt, keywordIt)  
                d.Add(keywordIif, keywordIif)  
                d.Add(keywordNew, keywordNew)  
                For Each type As Type In predefinedTypes  
                    d.Add(type.Name, type)  
                Next  
                Return d  
            End Function  
            Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T  
                target = value 
                Return value  
            End Function  
        End Class  
     
        NotInheritable Class Res  
            Private Sub New()  
            End Sub  
            Public Const DuplicateIdentifier As String = "The identifier '{0}' was defined more than once" 
            Public Const ExpressionTypeMismatch As String = "Expression of type '{0}' expected" 
            Public Const ExpressionExpected As String = "Expression expected" 
            Public Const InvalidCharacterLiteral As String = "Character literal must contain exactly one character" 
            Public Const InvalidIntegerLiteral As String = "Invalid integer literal '{0}'" 
            Public Const InvalidRealLiteral As String = "Invalid real literal '{0}'" 
            Public Const UnknownIdentifier As String = "Unknown identifier '{0}'" 
            Public Const NoItInScope As String = "No 'it' is in scope" 
            Public Const IifRequiresThreeArgs As String = "The 'iif' function requires three arguments" 
            Public Const FirstExprMustBeBool As String = "The first expression must be of type 'Boolean'" 
            Public Const BothTypesConvertToOther As String = "Both of the types '{0}' and '{1}' convert to the other" 
            Public Const NeitherTypeConvertsToOther As String = "Neither of the types '{0}' and '{1}' converts to the other" 
            Public Const MissingAsClause As String = "Expression is missing an 'as' clause" 
            Public Const ArgsIncompatibleWithLambda As String = "Argument list incompatible with lambda expression" 
            Public Const TypeHasNoNullableForm As String = "Type '{0}' has no nullable form" 
            Public Const NoMatchingConstructor As String = "No matching constructor in type '{0}'" 
            Public Const AmbiguousConstructorInvocation As String = "Ambiguous invocation of '{0}' constructor" 
            Public Const CannotConvertValue As String = "A value of type '{0}' cannot be converted to type '{1}'" 
            Public Const NoApplicableMethod As String = "No applicable method '{0}' exists in type '{1}'" 
            Public Const MethodsAreInaccessible As String = "Methods on type '{0}' are not accessible" 
            Public Const MethodIsVoid As String = "Method '{0}' in type '{1}' does not return a value" 
            Public Const AmbiguousMethodInvocation As String = "Ambiguous invocation of method '{0}' in type '{1}'" 
            Public Const UnknownPropertyOrField As String = "No property or field '{0}' exists in type '{1}'" 
            Public Const NoApplicableAggregate As String = "No applicable aggregate method '{0}' exists" 
            Public Const CannotIndexMultiDimArray As String = "Indexing of multi-dimensional arrays is not supported" 
            Public Const InvalidIndex As String = "Array index must be an integer expression" 
            Public Const NoApplicableIndexer As String = "No applicable indexer exists in type '{0}'" 
            Public Const AmbiguousIndexerInvocation As String = "Ambiguous invocation of indexer in type '{0}'" 
            Public Const IncompatibleOperand As String = "Operator '{0}' incompatible with operand type '{1}'" 
            Public Const IncompatibleOperands As String = "Operator '{0}' incompatible with operand types '{1}' and '{2}'" 
            Public Const UnterminatedStringLiteral As String = "Unterminated string literal" 
            Public Const InvalidCharacter As String = "Syntax error '{0}'" 
            Public Const DigitExpected As String = "Digit expected" 
            Public Const SyntaxError As String = "Syntax error" 
            Public Const TokenExpected As String = "{0} expected" 
            Public Const ParseExceptionFormat As String = "{0} (at index {1})" 
            Public Const ColonExpected As String = "':' expected" 
            Public Const OpenParenExpected As String = "'(' expected" 
            Public Const CloseParenOrOperatorExpected As String = "')' or operator expected" 
            Public Const CloseParenOrCommaExpected As String = "')' or ',' expected" 
            Public Const DotOrOpenParenExpected As String = "'.' or '(' expected" 
            Public Const OpenBracketExpected As String = "'[' expected" 
            Public Const CloseBracketOrCommaExpected As String = "']' or ',' expected" 
            Public Const IdentifierExpected As String = "Identifier expected" 
        End Class  
    End Namespace 
    I have finally converted the DataTable.cs and Dynamic.cs classes from Vlad's serialization example.  I will embed them here for anyone that is interested:
    DataTable.vb
    Imports System  
    Imports System.Collections.Generic  
    Imports System.Linq  
    Imports System.Collections  
    Imports System.Dynamic  
    Imports slSQLQueryWizard.SQLWiz.Dynamic  
    Namespace SQLWiz.Data  
        Public Class DataTable  
            Implements IEnumerable  
            Public Sub New(ByVal source As IEnumerable(Of Dictionary(Of String, Object)))  
                If source IsNot Nothing Then  
                    Dim firstItem = source.FirstOrDefault()  
     
                    If firstItem IsNot Nothing Then  
                        For Each key In firstItem  
                            Columns.Add(New DataColumn() With { _  
                             .ColumnName = key.Key, _  
                             .DataType = key.Value.[GetType]() _  
                            })  
                        Next  
     
                        For Each item In source  
                            Dim row = New SQLWiz.Data.myDataRow()  
     
                            For Each key In item  
                                row(key.Key) = key.Value  
                            Next  
                            Rows.Add(row)  
                        Next  
                    End If  
                End If  
            End Sub  
     
            Private m_columns As List(Of DataColumn) = Nothing  
            Public ReadOnly Property Columns() As List(Of DataColumn)  
                Get  
                    If m_columns Is Nothing Then  
                        m_columns = New List(Of DataColumn)()  
                    End If  
     
                    Return m_columns  
                End Get  
            End Property  
     
            Private m_rows As List(Of SQLWiz.Data.myDataRow) = Nothing  
            Public ReadOnly Property Rows() As List(Of SQLWiz.Data.myDataRow)  
                Get  
                    If m_rows Is Nothing Then  
                        m_rows = New List(Of SQLWiz.Data.myDataRow)()  
                    End If  
     
                    Return m_rows  
                End Get  
            End Property  
     
            Public Function NewRow() As Object  
                If queryable IsNot Nothing Then  
                    Return Activator.CreateInstance(queryable.ElementType)  
                End If  
     
                Return Nothing  
            End Function  
     
    #Region "IEnumerable Members"  
     
            Private queryable As IQueryable = Nothing 
            Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator  
                If queryable Is Nothing Then  
                    Dim type = ClassFactory.Instance.GetDynamicClass(Me.Columns.[Select](Function(c) New DynamicProperty(c.ColumnName, c.DataType)))  
                    Dim propertyInfos = type.GetProperties().ToList()  
     
                    Dim mylist = DirectCast(Activator.CreateInstance(GetType(List(Of )).MakeGenericType(type)), IList)  
                    For Each row In Me.Rows  
                        Dim item = Activator.CreateInstance(type)  
                        propertyInfos.ForEach(Sub(p) p.SetValue(item, row(p.Name), Nothing))  
                        mylist.Add(item)  
                    Next  
     
                    queryable = mylist.AsQueryable()  
                End If  
     
                Return queryable.GetEnumerator()  
            End Function  
    #End Region  
     
            Public Function ToList() As IList  
                Dim enumerator = GetEnumerator()  
                Dim list = DirectCast(Activator.CreateInstance(GetType(List(Of )).MakeGenericType(queryable.ElementType)), IList)  
                While enumerator.MoveNext()  
                    list.Add(enumerator.Current)  
                End While  
                Return list  
            End Function  
        End Class  
     
        Public Class DataColumn  
            Public Sub New()  
                DataType = GetType(Object)  
            End Sub  
     
            Public Property DataType() As Type  
                Get  
                    Return m_DataType  
                End Get  
                Set(ByVal value As Type)  
                    m_DataType = value 
                End Set  
            End Property  
            Private m_DataType As Type  
            Public Property ColumnName() As String  
                Get  
                    Return m_ColumnName  
                End Get  
                Set(ByVal value As String)  
                    m_ColumnName = value 
                End Set  
            End Property  
            Private m_ColumnName As String  
        End Class  
     
        Public Class myDataRow  
            Inherits Dictionary(Of String, Object)  
     
            '  
     
        End Class  
    End Namespace  
    '=======================================================  
    'Service provided by Telerik (www.telerik.com)  
    'Conversion powered by NRefactory.  
    'Twitter: @telerik, @toddanglin  
    'Facebook: facebook.com/telerik  
    '=======================================================  
     

    Dynamic.VB
    ''Copyright (C) Microsoft Corporation.  All rights reserved.  
     
    Imports System.Collections.Generic  
    Imports System.Text  
    Imports System.Linq  
    Imports System.Linq.Expressions  
    Imports System.Reflection  
    Imports System.Reflection.Emit  
    Imports System.Threading  
    Imports System.Dynamic  
    Imports System.Runtime.CompilerServices  
     
    Namespace SQLWiz.Dynamic  
        Module DynamicQueryable  
            Sub New()  
            End Sub  
            <Extension()> _  
            Public Function Where(Of T)(ByVal source As IQueryable(Of T), ByVal predicate As String, ByVal ParamArray values As Object()) As IQueryable(Of T)  
                Return DirectCast(Where(DirectCast(source, IQueryable), predicate, values), IQueryable(Of T))  
            End Function  
     
            <Extension()> _  
            Public Function Where(ByVal source As IQueryable, ByVal predicate As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If predicate Is Nothing Then  
                    Throw New ArgumentNullException("predicate")  
                End If  
                Dim lambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, GetType(Boolean), predicate, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Where", New Type() {source.ElementType}, source.Expression, Expression.Quote(lambda)))  
            End Function  
     
            <Extension()> _  
            Public Function [Select](ByVal source As IQueryable, ByVal selector As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If selector Is Nothing Then  
                    Throw New ArgumentNullException("selector")  
                End If  
                Dim lambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, selector, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Select", New Type() {source.ElementType, lambda.Body.Type}, source.Expression, Expression.Quote(lambda)))  
            End Function  
     
            <Extension()> _  
            Public Function OrderBy(Of T)(ByVal source As IQueryable(Of T), ByVal ordering As String, ByVal ParamArray values As Object()) As IQueryable(Of T)  
                Return DirectCast(OrderBy(DirectCast(source, IQueryable), ordering, values), IQueryable(Of T))  
            End Function  
     
            <Extension()> _  
            Public Function OrderBy(ByVal source As IQueryable, ByVal ordering As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If ordering Is Nothing Then  
                    Throw New ArgumentNullException("ordering")  
                End If  
                Dim parameters As ParameterExpression() = New ParameterExpression() {Expression.Parameter(source.ElementType, "")}  
                Dim parser As New ExpressionParser(parameters, ordering, values)  
                Dim orderings As IEnumerable(Of DynamicOrdering) = parser.ParseOrdering()  
                Dim queryExpr As Expression = source.Expression  
                Dim methodAsc As String = "OrderBy" 
                Dim methodDesc As String = "OrderByDescending" 
                For Each o As DynamicOrdering In orderings  
                    queryExpr = Expression.[Call](GetType(Queryable), If(o.Ascending, methodAsc, methodDesc), New Type() {source.ElementType, o.Selector.Type}, queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)))  
                    methodAsc = "ThenBy" 
                    methodDesc = "ThenByDescending" 
                Next  
                Return source.Provider.CreateQuery(queryExpr)  
            End Function  
     
            <Extension()> _  
            Public Function Take(ByVal source As IQueryable, ByVal count As Integer) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Take", New Type() {source.ElementType}, source.Expression, Expression.Constant(count)))  
            End Function  
     
            <Extension()> _  
            Public Function Skip(ByVal source As IQueryable, ByVal count As Integer) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Skip", New Type() {source.ElementType}, source.Expression, Expression.Constant(count)))  
            End Function  
     
            <Extension()> _  
            Public Function GroupBy(ByVal source As IQueryable, ByVal keySelector As String, ByVal elementSelector As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If keySelector Is Nothing Then  
                    Throw New ArgumentNullException("keySelector")  
                End If  
                If elementSelector Is Nothing Then  
                    Throw New ArgumentNullException("elementSelector")  
                End If  
                Dim keyLambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, keySelector, values)  
                Dim elementLambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, elementSelector, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "GroupBy", New Type() {source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type}, source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda)))  
            End Function  
     
            <Extension()> _  
            Public Function Any(ByVal source As IQueryable) As Boolean  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return CBool(source.Provider.Execute(Expression.[Call](GetType(Queryable), "Any", New Type() {source.ElementType}, source.Expression)))  
            End Function  
     
            <Extension()> _  
            Public Function Count(ByVal source As IQueryable) As Integer  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return CInt(source.Provider.Execute(Expression.[Call](GetType(Queryable), "Count", New Type() {source.ElementType}, source.Expression)))  
            End Function  
        End Module  
     
        Public MustInherit Class DynamicClass  
            Public Overrides Function ToString() As String  
                Dim props As PropertyInfo() = Me.[GetType]().GetProperties(BindingFlags.Instance Or BindingFlags.[Public])  
                Dim sb As New StringBuilder()  
                sb.Append("{")  
                For i As Integer = 0 To props.Length - 1  
                    If i > 0 Then  
                        sb.Append(", ")  
                    End If  
                    sb.Append(props(i).Name)  
                    sb.Append("=")  
                    sb.Append(props(i).GetValue(Me, Nothing))  
                Next  
                sb.Append("}")  
                Return sb.ToString()  
            End Function  
        End Class  
     
        Public Class DynamicProperty  
            Private m_name As String  
            Private m_type As Type  
     
            Public Sub New(ByVal name As String, ByVal type As Type)  
                If name Is Nothing Then  
                    Throw New ArgumentNullException("name")  
                End If  
                If type Is Nothing Then  
                    Throw New ArgumentNullException("type")  
                End If  
                Me.m_name = name  
                Me.m_type = type  
            End Sub  
     
            Public ReadOnly Property Name() As String  
                Get  
                    Return m_name  
                End Get  
            End Property  
     
            Public ReadOnly Property Type() As Type  
                Get  
                    Return m_type  
                End Get  
            End Property  
        End Class  
     
        Module DynamicExpression  
            Sub New()  
            End Sub  
            Public Function Parse(ByVal resultType As Type, ByVal expression As String, ByVal ParamArray values As Object()) As Expression  
                Dim parser As New ExpressionParser(Nothing, expression, values)  
                Return parser.Parse(resultType)  
            End Function  
     
            Public Function ParseLambda(ByVal itType As Type, ByVal resultType As Type, ByVal expression__1 As String, ByVal ParamArray values As Object()) As LambdaExpression  
                Return ParseLambda(New ParameterExpression() {Expression.Parameter(itType, "")}, resultType, expression__1, values)  
            End Function  
     
            Public Function ParseLambda(ByVal parameters As ParameterExpression(), ByVal resultType As Type, ByVal expression__1 As String, ByVal ParamArray values As Object()) As LambdaExpression  
                Dim parser As New ExpressionParser(parameters, expression__1, values)  
                Return Expression.Lambda(parser.Parse(resultType), parameters)  
            End Function  
     
            Public Function ParseLambda(Of T, S)(ByVal expression As String, ByVal ParamArray values As Object()) As Expression(Of Func(Of T, S))  
                Return DirectCast(ParseLambda(GetType(T), GetType(S), expression, values), Expression(Of Func(Of T, S)))  
            End Function  
     
            Public Function CreateClass(ByVal ParamArray properties As DynamicProperty()) As Type  
                Return ClassFactory.Instance.GetDynamicClass(properties)  
            End Function  
     
            Public Function CreateClass(ByVal properties As IEnumerable(Of DynamicProperty)) As Type  
                Return ClassFactory.Instance.GetDynamicClass(properties)  
            End Function  
        End Module  
     
        Friend Class DynamicOrdering  
            Public Selector As Expression  
            Public Ascending As Boolean  
        End Class  
     
        Friend Class Signature  
            Implements IEquatable(Of Signature)  
            Public properties As DynamicProperty()  
            Public hashCode As Integer  
     
            Public Sub New(ByVal properties As IEnumerable(Of DynamicProperty))  
                Me.properties = properties.ToArray()  
                hashCode = 0 
                For Each p As DynamicProperty In properties  
                    hashCodehashCode = hashCode Xor p.Name.GetHashCode() Xor p.Type.GetHashCode()  
                Next  
            End Sub  
     
            Public Overrides Function GetHashCode() As Integer  
                Return hashCode  
            End Function  
     
            Public Overrides Function Equals(ByVal obj As Object) As Boolean  
                Return If(TypeOf obj Is Signature, Equals(DirectCast(obj, Signature)), False)  
            End Function  
     
            Public Overloads Function Equals(ByVal other As Signature) As Boolean Implements IEquatable(Of Signature).Equals  
                If properties.Length <> other.properties.Length Then  
                    Return False  
                End If  
                For i As Integer = 0 To properties.Length - 1  
                    If properties(i).Name <> other.properties(i).Name OrElse properties(i).Type IsNot other.properties(i).Type Then  
                        Return False  
                    End If  
                Next  
                Return True  
            End Function  
        End Class  
     
        Friend Class ClassFactory  
            Public Shared ReadOnly Instance As New ClassFactory()  
     
            Shared Sub New()  
            End Sub  
            ' Trigger lazy initialization of static fields  
            Private [module] As ModuleBuilder  
            Private classes As Dictionary(Of Signature, Type)  
            Private classCount As Integer  
     
            Private Sub New()  
                Dim name As New AssemblyName("DynamicClasses")  
                Dim assembly As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run)  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                    New ReflectionPermission(PermissionState.Unrestricted).Assert()  
    #End If  
                Try  
                    [module] = assembly.DefineDynamicModule("Module")  
                Finally  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                    PermissionSet.RevertAssert()  
    #End If  
                End Try  
                classes = New Dictionary(Of Signature, Type)()  
            End Sub  
     
            Public Function GetDynamicClass(ByVal properties As IEnumerable(Of DynamicProperty)) As Type  
                Try  
                    Dim signature As New Signature(properties)  
                    Dim type As Type  
                    If Not classes.TryGetValue(signature, type) Then  
                        type = CreateDynamicClass(signature.properties)  
                        classes.Add(signature, type)  
                    End If  
                    Return type  
                Finally  
                End Try  
            End Function  
     
            Private Function CreateDynamicClass(ByVal properties As DynamicProperty()) As Type  
                Try  
                    Dim typeName As String = "DynamicClass" & (classCount + 1)  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                        New ReflectionPermission(PermissionState.Unrestricted).Assert()  
    #End If  
                    Try  
                        Dim tb As TypeBuilder = Me.[module].DefineType(typeName, TypeAttributes.[Class] Or TypeAttributes.[Public], GetType(DynamicClass))  
                        Dim fields As FieldInfo() = GenerateProperties(tb, properties)  
                        GenerateEquals(tb, fields)  
                        GenerateGetHashCode(tb, fields)  
                        Dim result As Type = tb.CreateType()  
                        classCount += 1  
                        Return result  
                    Finally  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                        PermissionSet.RevertAssert()  
    #End If  
                    End Try  
                Finally  
                End Try  
            End Function  
     
            Private Function GenerateProperties(ByVal tb As TypeBuilder, ByVal properties As DynamicProperty()) As FieldInfo()  
                Dim fields As FieldInfo() = New FieldBuilder(properties.Length - 1) {}  
                For i As Integer = 0 To properties.Length - 1  
                    Dim dp As DynamicProperty = properties(i)  
                    Dim fb As FieldBuilder = tb.DefineField("_" & dp.Name, dp.Type, FieldAttributes.[Private])  
                    Dim pb As PropertyBuilder = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, Nothing)  
                    Dim mbGet As MethodBuilder = tb.DefineMethod("get_" & dp.Name, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, dp.Type, Type.EmptyTypes)  
                    Dim genGet As ILGenerator = mbGet.GetILGenerator()  
                    genGet.Emit(OpCodes.Ldarg_0)  
                    genGet.Emit(OpCodes.Ldfld, fb)  
                    genGet.Emit(OpCodes.Ret)  
                    Dim mbSet As MethodBuilder = tb.DefineMethod("set_" & dp.Name, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, Nothing, New Type() {dp.Type})  
                    Dim genSet As ILGenerator = mbSet.GetILGenerator()  
                    genSet.Emit(OpCodes.Ldarg_0)  
                    genSet.Emit(OpCodes.Ldarg_1)  
                    genSet.Emit(OpCodes.Stfld, fb)  
                    genSet.Emit(OpCodes.Ret)  
                    pb.SetGetMethod(mbGet)  
                    pb.SetSetMethod(mbSet)  
                    fields(i) = fb  
                Next  
                Return fields  
            End Function  
     
            Private Sub GenerateEquals(ByVal tb As TypeBuilder, ByVal fields As FieldInfo())  
                Dim mb As MethodBuilder = tb.DefineMethod("Equals", MethodAttributes.[Public] Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig, GetType(Boolean), New Type() {GetType(Object)})  
                Dim gen As ILGenerator = mb.GetILGenerator()  
                Dim other As LocalBuilder = gen.DeclareLocal(tb)  
                Dim [next] As Label = gen.DefineLabel()  
                gen.Emit(OpCodes.Ldarg_1)  
                gen.Emit(OpCodes.Isinst, tb)  
                gen.Emit(OpCodes.Stloc, other)  
                gen.Emit(OpCodes.Ldloc, other)  
                gen.Emit(OpCodes.Brtrue_S, [next])  
                gen.Emit(OpCodes.Ldc_I4_0)  
                gen.Emit(OpCodes.Ret)  
                gen.MarkLabel([next])  
                For Each field As FieldInfo In fields  
                    Dim ft As Type = field.FieldType  
                    Dim ct As Type = GetType(EqualityComparer(Of )).MakeGenericType(ft)  
                    [next] = gen.DefineLabel()  
                    gen.EmitCall(OpCodes.[Call], ct.GetMethod("get_Default"), Nothing)  
                    gen.Emit(OpCodes.Ldarg_0)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.Emit(OpCodes.Ldloc, other)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", New Type() {ft, ft}), Nothing)  
                    gen.Emit(OpCodes.Brtrue_S, [next])  
                    gen.Emit(OpCodes.Ldc_I4_0)  
                    gen.Emit(OpCodes.Ret)  
                    gen.MarkLabel([next])  
                Next  
                gen.Emit(OpCodes.Ldc_I4_1)  
                gen.Emit(OpCodes.Ret)  
            End Sub  
     
            Private Sub GenerateGetHashCode(ByVal tb As TypeBuilder, ByVal fields As FieldInfo())  
                Dim mb As MethodBuilder = tb.DefineMethod("GetHashCode", MethodAttributes.[Public] Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig, GetType(Integer), Type.EmptyTypes)  
                Dim gen As ILGenerator = mb.GetILGenerator()  
                gen.Emit(OpCodes.Ldc_I4_0)  
                For Each field As FieldInfo In fields  
                    Dim ft As Type = field.FieldType  
                    Dim ct As Type = GetType(EqualityComparer(Of )).MakeGenericType(ft)  
                    gen.EmitCall(OpCodes.[Call], ct.GetMethod("get_Default"), Nothing)  
                    gen.Emit(OpCodes.Ldarg_0)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", New Type() {ft}), Nothing)  
                    gen.Emit(OpCodes.[Xor])  
                Next  
                gen.Emit(OpCodes.Ret)  
            End Sub  
        End Class  
     
        Public NotInheritable Class ParseException  
            Inherits Exception  
            Private m_position As Integer  
     
            Public Sub New(ByVal message As String, ByVal position As Integer)  
                MyBase.New(message)  
                Me.m_position = position  
            End Sub  
     
            Public ReadOnly Property Position() As Integer  
                Get  
                    Return m_position  
                End Get  
            End Property  
     
            Public Overrides Function ToString() As String  
                Return String.Format(Res.ParseExceptionFormat, Message, m_position)  
            End Function  
        End Class  
     
        Friend Class ExpressionParser  
            Private Structure myToken  
                Public id As TokenId  
                Public text As String  
                Public pos As Integer  
            End Structure  
     
            Private Enum TokenId  
                Unknown  
                [End]  
                Identifier  
                StringLiteral  
                IntegerLiteral  
                RealLiteral  
                Exclamation  
                Percent  
                Amphersand  
                OpenParen  
                CloseParen  
                Asterisk  
                Plus  
                Comma  
                Minus  
                Dot  
                Slash  
                Colon  
                LessThan  
                Equal  
                GreaterThan  
                Question  
                OpenBracket  
                CloseBracket  
                Bar  
                ExclamationEqual  
                DoubleAmphersand  
                LessThanEqual  
                LessGreater  
                DoubleEqual  
                GreaterThanEqual  
                DoubleBar  
            End Enum  
     
            Private Interface ILogicalSignatures  
                Sub F(ByVal x As Boolean, ByVal y As Boolean)  
                Sub F(ByVal x As Global.System.Nullable(Of Boolean), ByVal y As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IArithmeticSignatures  
                Sub F(ByVal x As Integer, ByVal y As Integer)  
                Sub F(ByVal x As UInteger, ByVal y As UInteger)  
                Sub F(ByVal x As Long, ByVal y As Long)  
                Sub F(ByVal x As ULong, ByVal y As ULong)  
                Sub F(ByVal x As Single, ByVal y As Single)  
                Sub F(ByVal x As Double, ByVal y As Double)  
                Sub F(ByVal x As Decimal, ByVal y As Decimal)  
                Sub F(ByVal x As Global.System.Nullable(Of Integer), ByVal y As Global.System.Nullable(Of Integer))  
                Sub F(ByVal x As Global.System.Nullable(Of UInteger), ByVal y As Global.System.Nullable(Of UInteger))  
                Sub F(ByVal x As Global.System.Nullable(Of Long), ByVal y As Global.System.Nullable(Of Long))  
                Sub F(ByVal x As Global.System.Nullable(Of ULong), ByVal y As Global.System.Nullable(Of ULong))  
                Sub F(ByVal x As Global.System.Nullable(Of Single), ByVal y As Global.System.Nullable(Of Single))  
                Sub F(ByVal x As Global.System.Nullable(Of Double), ByVal y As Global.System.Nullable(Of Double))  
                Sub F(ByVal x As Global.System.Nullable(Of Decimal), ByVal y As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Private Interface IRelationalSignatures  
                Inherits IArithmeticSignatures  
                Overloads Sub F(ByVal x As String, ByVal y As String)  
                Overloads Sub F(ByVal x As Char, ByVal y As Char)  
                Overloads Sub F(ByVal x As DateTime, ByVal y As DateTime)  
                Overloads Sub F(ByVal x As TimeSpan, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of Char), ByVal y As Global.System.Nullable(Of Char))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of DateTime))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of TimeSpan), ByVal y As Global.System.Nullable(Of TimeSpan))  
            End Interface  
     
            Private Interface IEqualitySignatures  
                Inherits IRelationalSignatures  
                Overloads Sub F(ByVal x As Boolean, ByVal y As Boolean)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of Boolean), ByVal y As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IAddSignatures  
                Inherits IArithmeticSignatures  
                Overloads Sub F(ByVal x As DateTime, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As TimeSpan, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of TimeSpan))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of TimeSpan), ByVal y As Global.System.Nullable(Of TimeSpan))  
            End Interface  
     
            Private Interface ISubtractSignatures  
                Inherits IAddSignatures  
                Overloads Sub F(ByVal x As DateTime, ByVal y As DateTime)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of DateTime))  
            End Interface  
     
            Private Interface INegationSignatures  
                Sub F(ByVal x As Integer)  
                Sub F(ByVal x As Long)  
                Sub F(ByVal x As Single)  
                Sub F(ByVal x As Double)  
                Sub F(ByVal x As Decimal)  
                Sub F(ByVal x As Global.System.Nullable(Of Integer))  
                Sub F(ByVal x As Global.System.Nullable(Of Long))  
                Sub F(ByVal x As Global.System.Nullable(Of Single))  
                Sub F(ByVal x As Global.System.Nullable(Of Double))  
                Sub F(ByVal x As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Private Interface INotSignatures  
                Sub F(ByVal x As Boolean)  
                Sub F(ByVal x As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IEnumerableSignatures  
                Sub Where(ByVal predicate As Boolean)  
                Sub Any()  
                Sub Any(ByVal predicate As Boolean)  
                Sub All(ByVal predicate As Boolean)  
                Sub Count()  
                Sub Count(ByVal predicate As Boolean)  
                Sub Min(ByVal selector As Object)  
                Sub Max(ByVal selector As Object)  
                Sub Sum(ByVal selector As Integer)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Integer))  
                Sub Sum(ByVal selector As Long)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Long))  
                Sub Sum(ByVal selector As Single)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Single))  
                Sub Sum(ByVal selector As Double)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Double))  
                Sub Sum(ByVal selector As Decimal)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Decimal))  
                Sub Average(ByVal selector As Integer)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Integer))  
                Sub Average(ByVal selector As Long)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Long))  
                Sub Average(ByVal selector As Single)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Single))  
                Sub Average(ByVal selector As Double)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Double))  
                Sub Average(ByVal selector As Decimal)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Shared ReadOnly predefinedTypes As Type() = {GetType([Object]), GetType([Boolean]), GetType([Char]), GetType([String]), GetType([SByte]), GetType([Byte]), _  
             GetType(Int16), GetType(UInt16), GetType(Int32), GetType(UInt32), GetType(Int64), GetType(UInt64), _  
             GetType([Single]), GetType([Double]), GetType([Decimal]), GetType(DateTime), GetType(TimeSpan), GetType(Guid), _  
             GetType(Math), GetType(Convert)}  
     
            Shared ReadOnly trueLiteral As ExpressionExpression = Expression.Constant(True)  
            Shared ReadOnly falseLiteral As ExpressionExpression = Expression.Constant(False)  
            Shared ReadOnly nullLiteral As ExpressionExpression = Expression.Constant(Nothing)  
     
            Shared ReadOnly keywordIt As String = "it" 
            Shared ReadOnly keywordIif As String = "iif" 
            Shared ReadOnly keywordNew As String = "new" 
     
            Shared keywords As Dictionary(Of String, Object)  
     
            Private symbols As Dictionary(Of String, Object)  
            Private externals As IDictionary(Of String, Object)  
            Private literals As Dictionary(Of Expression, String)  
            Private it As ParameterExpression  
            Private text As String  
            Private textPos As Integer  
            Private textLen As Integer  
            Private ch As Char  
            Private varToken As myToken  
     
            Public Sub New(ByVal parameters As ParameterExpression(), ByVal expression As String, ByVal values As Object())  
                If expression Is Nothing Then  
                    Throw New ArgumentNullException("expression")  
                End If  
                If keywords Is Nothing Then  
                    keywords = CreateKeywords()  
                End If  
                symbols = New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)  
                literals = New Dictionary(Of Expression, String)()  
                If parameters IsNot Nothing Then  
                    ProcessParameters(parameters)  
                End If  
                If values IsNot Nothing Then  
                    ProcessValues(values)  
                End If  
                text = expression 
                texttextLen = text.Length  
                SetTextPos(0)  
                NextToken()  
            End Sub  
     
            Private Sub ProcessParameters(ByVal parameters As ParameterExpression())  
                For Each pe As ParameterExpression In parameters  
                    If Not [String].IsNullOrEmpty(pe.Name) Then  
                        AddSymbol(pe.Name, pe)  
                    End If  
                Next  
                If parameters.Length = 1 AndAlso [String].IsNullOrEmpty(parameters(0).Name) Then  
                    it = parameters(0)  
                End If  
            End Sub  
     
            Private Sub ProcessValues(ByVal values As Object())  
                For i As Integer = 0 To values.Length - 1  
                    Dim value As Object = values(i)  
                    If i = values.Length - 1 AndAlso TypeOf value Is IDictionary(Of String, Object) Then  
                        externals = DirectCast(value, IDictionary(Of String, Object))  
                    Else  
                        AddSymbol("@" & i.ToString(Globalization.CultureInfo.InvariantCulture), value)  
                    End If  
                Next  
            End Sub  
     
            Private Sub AddSymbol(ByVal name As String, ByVal value As Object)  
                If symbols.ContainsKey(name) Then  
                    Throw ParseError(Res.DuplicateIdentifier, name)  
                End If  
                symbols.Add(name, value)  
            End Sub  
     
            Public Function Parse(ByVal resultType As Type) As Expression  
                Dim exprPos As Integer = varToken.pos  
                Dim expr As Expression = ParseExpression()  
                If resultType IsNot Nothing Then  
                    If (InlineAssignHelper(expr, PromoteExpression(expr, resultType, True))) Is Nothing Then  
                        Throw ParseError(exprPos, Res.ExpressionTypeMismatch, GetTypeName(resultType))  
                    End If  
                End If  
                ValidateToken(TokenId.[End], Res.SyntaxError)  
                Return expr  
            End Function  
     
            '#Pragma warning disable 0219  
            Public Function ParseOrdering() As IEnumerable(Of DynamicOrdering)  
                Dim orderings As New List(Of DynamicOrdering)()  
                While True  
                    Dim expr As Expression = ParseExpression()  
                    Dim ascending As Boolean = True 
                    If TokenIdentifierIs("asc") OrElse TokenIdentifierIs("ascending") Then  
                        NextToken()  
                    ElseIf TokenIdentifierIs("desc") OrElse TokenIdentifierIs("descending") Then  
                        NextToken()  
                        ascending = False 
                    End If  
                    orderings.Add(New DynamicOrdering() With { _  
                      .Selector = expr, _  
                      .Ascending = ascending _  
                    })  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                ValidateToken(TokenId.[End], Res.SyntaxError)  
                Return orderings  
            End Function  
            '#Pragma warning restore 0219  
     
            ' ?: operator  
            Private Function ParseExpression() As Expression  
                Dim errorPos As Integer = varToken.pos  
                Dim expr As Expression = ParseLogicalOr()  
                If varToken.id = TokenId.Question Then  
                    NextToken()  
                    Dim expr1 As Expression = ParseExpression()  
                    ValidateToken(TokenId.Colon, Res.ColonExpected)  
                    NextToken()  
                    Dim expr2 As Expression = ParseExpression()  
                    expr = GenerateConditional(expr, expr1, expr2, errorPos)  
                End If  
                Return expr  
            End Function  
     
            ' ||, or operator  
            Private Function ParseLogicalOr() As Expression  
                Dim left As Expression = ParseLogicalAnd()  
                While varToken.id = TokenId.DoubleBar OrElse TokenIdentifierIs("or")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseLogicalAnd()  
                    CheckAndPromoteOperands(GetType(ILogicalSignatures), op.text, left, right, op.pos)  
                    left = Expression.[OrElse](left, right)  
                End While  
                Return left  
            End Function  
     
            ' &&, and operator  
            Private Function ParseLogicalAnd() As Expression  
                Dim left As Expression = ParseComparison()  
                While varToken.id = TokenId.DoubleAmphersand OrElse TokenIdentifierIs("and")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseComparison()  
                    CheckAndPromoteOperands(GetType(ILogicalSignatures), op.text, left, right, op.pos)  
                    left = Expression.[AndAlso](left, right)  
                End While  
                Return left  
            End Function  
     
            ' =, ==, !=, <>, >>=, <<= operators  
            Private Function ParseComparison() As Expression  
                Dim left As Expression = ParseAdditive()  
                While varToken.id = TokenId.Equal OrElse varToken.id = TokenId.DoubleEqual OrElse varToken.id = TokenId.ExclamationEqual OrElse varToken.id = TokenId.LessGreater OrElse varToken.id = TokenId.GreaterThan OrElse varToken.id = TokenId.GreaterThanEqual OrElse varToken.id = TokenId.LessThan OrElse varToken.id = TokenId.LessThanEqual  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseAdditive()  
                    Dim isEquality As Boolean = op.id = TokenId.Equal OrElse op.id = TokenId.DoubleEqual OrElse op.id = TokenId.ExclamationEqual OrElse op.id = TokenId.LessGreater  
                    If isEquality AndAlso Not left.Type.IsValueType AndAlso Not right.Type.IsValueType Then  
                        If Not left.Type.Equals(right.Type) Then  
                            If left.Type.IsAssignableFrom(right.Type) Then  
                                right = Expression.Convert(right, left.Type)  
                            ElseIf right.Type.IsAssignableFrom(left.Type) Then  
                                left = Expression.Convert(left, right.Type)  
                            Else  
                                Throw IncompatibleOperandsError(op.text, left, right, op.pos)  
                            End If  
                        End If  
                    ElseIf IsEnumType(left.Type) OrElse IsEnumType(right.Type) Then  
                        If Not left.Type.Equals(right.Type) Then  
                            Dim e As Expression  
                            If (InlineAssignHelper(e, PromoteExpression(right, left.Type, True))) IsNot Nothing Then  
                                right = e 
                            ElseIf (InlineAssignHelper(e, PromoteExpression(left, right.Type, True))) IsNot Nothing Then  
                                left = e  
                            Else  
                                Throw IncompatibleOperandsError(op.text, left, right, op.pos)  
                            End If  
                        End If  
                    Else  
                        CheckAndPromoteOperands(If(isEquality, GetType(IEqualitySignatures), GetType(IRelationalSignatures)), op.text, left, right, op.pos)  
                    End If  
                    Select Case op.id  
                        Case TokenId.Equal, TokenId.DoubleEqual  
                            left = GenerateEqual(left, right)  
                            Exit Select  
                        Case TokenId.ExclamationEqual, TokenId.LessGreater  
                            left = GenerateNotEqual(left, right)  
                            Exit Select  
                        Case TokenId.GreaterThan  
                            left = GenerateGreaterThan(left, right)  
                            Exit Select  
                        Case TokenId.GreaterThanEqual  
                            left = GenerateGreaterThanEqual(left, right)  
                            Exit Select  
                        Case TokenId.LessThan  
                            left = GenerateLessThan(left, right)  
                            Exit Select  
                        Case TokenId.LessThanEqual  
                            left = GenerateLessThanEqual(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' +, -, & operators  
            Private Function ParseAdditive() As Expression  
                Dim left As Expression = ParseMultiplicative()  
                While varToken.id = TokenId.Plus OrElse varToken.id = TokenId.Minus OrElse varToken.id = TokenId.Amphersand  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseMultiplicative()  
                    Select Case op.id  
                        Case TokenId.Plus  
                            If left.Type.Equals(GetType(String)) OrElse right.Type.Equals(GetType(String)) Then  
                                left = GenerateStringConcat(left, right)  
                                Exit Select  
                            End If  
                            CheckAndPromoteOperands(GetType(IAddSignatures), op.text, left, right, op.pos)  
                            left = GenerateAdd(left, right)  
                            Exit Select  
                        Case TokenId.Minus  
                            CheckAndPromoteOperands(GetType(ISubtractSignatures), op.text, left, right, op.pos)  
                            left = GenerateSubtract(left, right)  
                            Exit Select  
                        Case TokenId.Amphersand  
                            left = GenerateStringConcat(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' *, /, %, mod operators  
            Private Function ParseMultiplicative() As Expression  
                Dim left As Expression = ParseUnary()  
                While varToken.id = TokenId.Asterisk OrElse varToken.id = TokenId.Slash OrElse varToken.id = TokenId.Percent OrElse TokenIdentifierIs("mod")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseUnary()  
                    CheckAndPromoteOperands(GetType(IArithmeticSignatures), op.text, left, right, op.pos)  
                    Select Case op.id  
                        Case TokenId.Asterisk  
                            left = Expression.Multiply(left, right)  
                            Exit Select  
                        Case TokenId.Slash  
                            left = Expression.Divide(left, right)  
                            Exit Select  
                        Case TokenId.Percent, TokenId.Identifier  
                            left = Expression.Modulo(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' -, !, not unary operators  
            Private Function ParseUnary() As Expression  
                If varToken.id = TokenId.Minus OrElse varToken.id = TokenId.Exclamation OrElse TokenIdentifierIs("not") Then  
                    Dim op As myToken = varToken 
                    NextToken()  
                    If op.id = TokenId.Minus AndAlso (varToken.id = TokenId.IntegerLiteral OrElse varToken.id = TokenId.RealLiteral) Then  
                        varToken.text = "-" & varToken.text  
                        varToken.pos = op.pos  
                        Return ParsePrimary()  
                    End If  
                    Dim expr As Expression = ParseUnary()  
                    If op.id = TokenId.Minus Then  
                        CheckAndPromoteOperand(GetType(INegationSignatures), op.text, expr, op.pos)  
                        expr = Expression.Negate(expr)  
                    Else  
                        CheckAndPromoteOperand(GetType(INotSignatures), op.text, expr, op.pos)  
                        expr = Expression.[Not](expr)  
                    End If  
                    Return expr  
                End If  
                Return ParsePrimary()  
            End Function  
     
            Private Function ParsePrimary() As Expression  
                Dim expr As Expression = ParsePrimaryStart()  
                While True  
                    If varToken.id = TokenId.Dot Then  
                        NextToken()  
                        expr = ParseMemberAccess(Nothing, expr)  
                    ElseIf varToken.id = TokenId.OpenBracket Then  
                        expr = ParseElementAccess(expr)  
                    Else  
                        Exit While  
                    End If  
                End While  
                Return expr  
            End Function  
     
            Private Function ParsePrimaryStart() As Expression  
                Select Case varToken.id  
                    Case TokenId.Identifier  
                        Return ParseIdentifier()  
                    Case TokenId.StringLiteral  
                        Return ParseStringLiteral()  
                    Case TokenId.IntegerLiteral  
                        Return ParseIntegerLiteral()  
                    Case TokenId.RealLiteral  
                        Return ParseRealLiteral()  
                    Case TokenId.OpenParen  
                        Return ParseParenExpression()  
                    Case Else  
                        Throw ParseError(Res.ExpressionExpected)  
                End Select  
            End Function  
     
            Private Function ParseStringLiteral() As Expression  
                ValidateToken(TokenId.StringLiteral)  
                Dim quote As Char = varToken.text(0)  
                Dim s As String = varToken.text.Substring(1, varToken.text.Length - 2)  
                Dim start As Integer = 0 
                While True  
                    Dim i As Integer = s.IndexOf(quote, start)  
                    If i < 0 Then  
                        Exit While  
                    End If  
                    ss = s.Remove(i, 1)  
                    start = i + 1  
                End While  
                If quote = "'"c Then  
                    If s.Length <> 1 Then  
                        Throw ParseError(Res.InvalidCharacterLiteral)  
                    End If  
                    NextToken()  
                    Return CreateLiteral(s(0), s)  
                End If  
                NextToken()  
                Return CreateLiteral(s, s)  
            End Function  
     
            Private Function ParseIntegerLiteral() As Expression  
                ValidateToken(TokenId.IntegerLiteral)  
                Dim text As String = varToken.text  
                If text(0) <> "-"c Then  
                    Dim value As ULong  
                    If Not UInt64.TryParse(text, value) Then  
                        Throw ParseError(Res.InvalidIntegerLiteral, text)  
                    End If  
                    NextToken()  
                    If value <= CULng(Int32.MaxValue) Then  
                        Return CreateLiteral(CInt(value), text)  
                    End If  
                    If value <= CULng(UInt32.MaxValue) Then  
                        Return CreateLiteral(CUInt(value), text)  
                    End If  
                    If value <= CULng(Int64.MaxValue) Then  
                        Return CreateLiteral(CLng(value), text)  
                    End If  
                    Return CreateLiteral(value, text)  
                Else  
                    Dim value As Long  
                    If Not Int64.TryParse(text, value) Then  
                        Throw ParseError(Res.InvalidIntegerLiteral, text)  
                    End If  
                    NextToken()  
                    If value >= Int32.MinValue AndAlso value <= Int32.MaxValue Then  
                        Return CreateLiteral(CInt(value), text)  
                    End If  
                    Return CreateLiteral(value, text)  
                End If  
            End Function  
     
            Private Function ParseRealLiteral() As Expression  
                ValidateToken(TokenId.RealLiteral)  
                Dim text As String = varToken.text  
                Dim value As Object = Nothing 
                Dim last As Char = text(text.Length - 1)  
                If last = "F"c OrElse last = "f"c Then  
                    Dim f As Single  
                    If [Single].TryParse(text.Substring(0, text.Length - 1), f) Then  
                        value = f 
                    End If  
                Else  
                    Dim d As Double  
                    If [Double].TryParse(text, d) Then  
                        value = d 
                    End If  
                End If  
                If value Is Nothing Then  
                    Throw ParseError(Res.InvalidRealLiteral, text)  
                End If  
                NextToken()  
                Return CreateLiteral(value, text)  
            End Function  
     
            Private Function CreateLiteral(ByVal value As Object, ByVal text As String) As Expression  
                Dim expr As ConstantExpression = Expression.Constant(value)  
                literals.Add(expr, text)  
                Return expr  
            End Function  
     
            Private Function ParseParenExpression() As Expression  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim e As Expression = ParseExpression()  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected)  
                NextToken()  
                Return e  
            End Function  
     
            Private Function ParseIdentifier() As Expression  
                ValidateToken(TokenId.Identifier)  
                Dim value As Object  
                If keywords.TryGetValue(varToken.text, value) Then  
                    If TypeOf value Is Type Then  
                        Return ParseTypeAccess(DirectCast(value, Type))  
                    End If  
                    If value Is DirectCast(keywordIt, Object) Then  
                        Return ParseIt()  
                    End If  
                    If value Is DirectCast(keywordIif, Object) Then  
                        Return ParseIif()  
                    End If  
                    If value Is DirectCast(keywordNew, Object) Then  
                        Return ParseNew()  
                    End If  
                    NextToken()  
                    Return DirectCast(value, Expression)  
                End If  
                If symbols.TryGetValue(varToken.text, value) OrElse externals IsNot Nothing AndAlso externals.TryGetValue(varToken.text, value) Then  
                    Dim expr As Expression = TryCast(value, Expression)  
                    If expr Is Nothing Then  
                        expr = Expression.Constant(value)  
                    Else  
                        Dim lambda As LambdaExpression = TryCast(expr, LambdaExpression)  
                        If lambda IsNot Nothing Then  
                            Return ParseLambdaInvocation(lambda)  
                        End If  
                    End If  
                    NextToken()  
                    Return expr  
                End If  
                If it IsNot Nothing Then  
                    Return ParseMemberAccess(Nothing, it)  
                End If  
                Throw ParseError(Res.UnknownIdentifier, varToken.text)  
            End Function  
     
            Private Function ParseIt() As Expression  
                If it Is Nothing Then  
                    Throw ParseError(Res.NoItInScope)  
                End If  
                NextToken()  
                Return it  
            End Function  
     
            Private Function ParseIif() As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                Dim args As Expression() = ParseArgumentList()  
                If args.Length <> 3 Then  
                    Throw ParseError(errorPos, Res.IifRequiresThreeArgs)  
                End If  
                Return GenerateConditional(args(0), args(1), args(2), errorPos)  
            End Function  
     
            Private Function GenerateConditional(ByVal test As Expression, ByVal expr1 As Expression, ByVal expr2 As Expression, ByVal errorPos As Integer) As Expression  
                If Not test.Type.Equals(GetType(Boolean)) Then  
                    Throw ParseError(errorPos, Res.FirstExprMustBeBool)  
                End If  
                If Not expr1.Type.Equals(expr2.Type) Then  
                    Dim expr1as2 As Expression = If(Not expr2.Equals(nullLiteral), PromoteExpression(expr1, expr2.Type, True), Nothing)  
                    Dim expr2as1 As Expression = If(Not expr2.Equals(nullLiteral), PromoteExpression(expr2, expr1.Type, True), Nothing)  
                    If expr1as2 IsNot Nothing AndAlso expr2as1 Is Nothing Then  
                        expr1 = expr1as2 
                    ElseIf expr2as1 IsNot Nothing AndAlso expr1as2 Is Nothing Then  
                        expr2 = expr2as1 
                    Else  
                        Dim type1 As String = If(Not expr2.Equals(nullLiteral), expr1.Type.Name, "null")  
                        Dim type2 As String = If(Not expr2.Equals(nullLiteral), expr2.Type.Name, "null")  
                        If expr1as2 IsNot Nothing AndAlso expr2as1 IsNot Nothing Then  
                            Throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2)  
                        End If  
                        Throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2)  
                    End If  
                End If  
                Return Expression.Condition(test, expr1, expr2)  
            End Function  
     
            Private Function ParseNew() As Expression  
                NextToken()  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim properties As New List(Of DynamicProperty)()  
                Dim expressions As New List(Of Expression)()  
                While True  
                    Dim exprPos As Integer = varToken.pos  
                    Dim expr As Expression = ParseExpression()  
                    Dim propName As String  
                    If TokenIdentifierIs("as") Then  
                        NextToken()  
                        propName = GetIdentifier()  
                        NextToken()  
                    Else  
                        Dim [me] As MemberExpression = TryCast(expr, MemberExpression)  
                        If [me] Is Nothing Then  
                            Throw ParseError(exprPos, Res.MissingAsClause)  
                        End If  
                        propName = [me].Member.Name  
                    End If  
                    expressions.Add(expr)  
                    properties.Add(New DynamicProperty(propName, expr.Type))  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)  
                NextToken()  
                Dim type As Type = DynamicExpression.CreateClass(properties)  
                Dim bindings As MemberBinding() = New MemberBinding(properties.Count - 1) {}  
                For i As Integer = 0 To bindings.Length - 1  
                    bindings(i) = Expression.Bind(type.GetProperty(properties(i).Name), expressions(i))  
                Next  
                Return Expression.MemberInit(Expression.[New](type), bindings)  
            End Function  
     
            Private Function ParseLambdaInvocation(ByVal lambda As LambdaExpression) As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                Dim args As Expression() = ParseArgumentList()  
                Dim method As MethodBase  
                If FindMethod(lambda.Type, "Invoke", False, args, method) <> 1 Then  
                    Throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda)  
                End If  
                Return Expression.Invoke(lambda, args)  
            End Function  
     
            Private Function ParseTypeAccess(ByVal type As Type) As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                If varToken.id = TokenId.Question Then  
                    If Not type.IsValueType OrElse IsNullableType(type) Then  
                        Throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type))  
                    End If  
                    type = GetType(Nullable(Of )).MakeGenericType(type)  
                    NextToken()  
                End If  
                If varToken.id = TokenId.OpenParen Then  
                    Dim args As Expression() = ParseArgumentList()  
                    Dim method As MethodBase  
                    Select Case FindBestMethod(type.GetConstructors(), args, method)  
                        Case 0  
                            If args.Length = 1 Then  
                                Return GenerateConversion(args(0), type, errorPos)  
                            End If  
                            Throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type))  
                        Case 1  
                            Return Expression.[New](DirectCast(method, ConstructorInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type))  
                    End Select  
                End If  
                ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected)  
                NextToken()  
                Return ParseMemberAccess(type, Nothing)  
            End Function  
     
            Private Function GenerateConversion(ByVal expr As Expression, ByVal type As Type, ByVal errorPos As Integer) As Expression  
                Dim exprType As Type = expr.Type  
                If exprType Is type Then  
                    Return expr  
                End If  
                If exprType.IsValueType AndAlso type.IsValueType Then  
                    If (IsNullableType(exprType) OrElse IsNullableType(type)) AndAlso GetNonNullableType(exprType) Is GetNonNullableType(type) Then  
                        Return Expression.Convert(expr, type)  
                    End If  
                    If (IsNumericType(exprType) OrElse IsEnumType(exprType)) AndAlso (IsNumericType(type)) OrElse IsEnumType(type) Then  
                        Return Expression.ConvertChecked(expr, type)  
                    End If  
                End If  
                If exprType.IsAssignableFrom(type) OrElse type.IsAssignableFrom(exprType) OrElse exprType.IsInterface OrElse type.IsInterface Then  
                    Return Expression.Convert(expr, type)  
                End If  
                Throw ParseError(errorPos, Res.CannotConvertValue, GetTypeName(exprType), GetTypeName(type))  
            End Function  
     
            Private Function ParseMemberAccess(ByVal type As Type, ByVal instance As Expression) As Expression  
                If instance IsNot Nothing Then  
                    type = instance.Type  
                End If  
                Dim errorPos As Integer = varToken.pos  
                Dim id As String = GetIdentifier()  
                NextToken()  
                If varToken.id = TokenId.OpenParen Then  
                    If instance IsNot Nothing AndAlso type IsNot GetType(String) Then  
                        Dim enumerableType As Type = FindGenericType(GetType(IEnumerable(Of )), type)  
                        If enumerableType IsNot Nothing Then  
                            Dim elementType As Type = enumerableType.GetGenericArguments()(0)  
                            Return ParseAggregate(instance, elementType, id, errorPos)  
                        End If  
                    End If  
                    Dim args As Expression() = ParseArgumentList()  
                    Dim mb As MethodBase  
                    Select Case FindMethod(type, id, instance Is Nothing, args, mb)  
                        Case 0  
                            Throw ParseError(errorPos, Res.NoApplicableMethod, id, GetTypeName(type))  
                        Case 1  
                            Dim method As MethodInfo = DirectCast(mb, MethodInfo)  
                            If Not IsPredefinedType(method.DeclaringType) Then  
                                Throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType))  
                            End If  
                            If method.ReturnType Is GetType(Void) Then  
                                Throw ParseError(errorPos, Res.MethodIsVoid, id, GetTypeName(method.DeclaringType))  
                            End If  
                            Return Expression.[Call](instance, DirectCast(method, MethodInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousMethodInvocation, id, GetTypeName(type))  
                    End Select  
                Else  
                    Dim member As MemberInfo = FindPropertyOrField(type, id, instance Is Nothing)  
                    If member Is Nothing Then  
                        Throw ParseError(errorPos, Res.UnknownPropertyOrField, id, GetTypeName(type))  
                    End If  
                    Return If(TypeOf member Is PropertyInfo, Expression.[Property](instance, DirectCast(member, PropertyInfo)), Expression.Field(instance, DirectCast(member, FieldInfo)))  
                End If  
            End Function  
     
            Private Shared Function FindGenericType(ByVal generic As Type, ByVal type As Type) As Type  
                While type IsNot Nothing AndAlso type IsNot GetType(Object)  
                    If type.IsGenericType AndAlso type.GetGenericTypeDefinition() Is generic Then  
                        Return type  
                    End If  
                    If generic.IsInterface Then  
                        For Each intfType As Type In type.GetInterfaces()  
                            Dim found As Type = FindGenericType(generic, intfType)  
                            If found IsNot Nothing Then  
                                Return found  
                            End If  
                        Next  
                    End If  
                    typetype = type.BaseType  
                End While  
                Return Nothing  
            End Function  
     
            Private Function ParseAggregate(ByVal instance As Expression, ByVal elementType As Type, ByVal methodName As String, ByVal errorPos As Integer) As Expression  
                Dim outerIt As ParameterExpression = it 
                Dim innerIt As ParameterExpression = Expression.Parameter(elementType, "")  
                it = innerIt 
                Dim args As Expression() = ParseArgumentList()  
                it = outerIt 
                Dim signature As MethodBase  
                If FindMethod(GetType(IEnumerableSignatures), methodName, False, args, signature) <> 1 Then  
                    Throw ParseError(errorPos, Res.NoApplicableAggregate, methodName)  
                End If  
                Dim typeArgs As Type()  
                If signature.Name = "Min" OrElse signature.Name = "Max" Then  
                    typeArgs = New Type() {elementType, args(0).Type}  
                Else  
                    typeArgs = New Type() {elementType}  
                End If  
                If args.Length = 0 Then  
                    args = New Expression() {instance}  
                Else  
                    args = New Expression() {instance, Expression.Lambda(args(0), innerIt)}  
                End If  
                Return Expression.[Call](GetType(Enumerable), signature.Name, typeArgs, args)  
            End Function  
     
            Private Function ParseArgumentList() As Expression()  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim args As Expression() = If(varToken.id <> TokenId.CloseParen, ParseArguments(), New Expression(-1) {})  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)  
                NextToken()  
                Return args  
            End Function  
     
            Private Function ParseArguments() As Expression()  
                Dim argList As New List(Of Expression)()  
                While True  
                    argList.Add(ParseExpression())  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                Return argList.ToArray()  
            End Function  
     
            Private Function ParseElementAccess(ByVal expr As Expression) As Expression  
                Dim errorPos As Integer = varToken.pos  
                ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected)  
                NextToken()  
                Dim args As Expression() = ParseArguments()  
                ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected)  
                NextToken()  
                If expr.Type.IsArray Then  
                    If expr.Type.GetArrayRank() <> 1 OrElse args.Length <> 1 Then  
                        Throw ParseError(errorPos, Res.CannotIndexMultiDimArray)  
                    End If  
                    Dim index As Expression = PromoteExpression(args(0), GetType(Integer), True)  
                    If index Is Nothing Then  
                        Throw ParseError(errorPos, Res.InvalidIndex)  
                    End If  
                    Return Expression.ArrayIndex(expr, index)  
                Else  
                    Dim mb As MethodBase  
                    Select Case FindIndexer(expr.Type, args, mb)  
                        Case 0  
                            Throw ParseError(errorPos, Res.NoApplicableIndexer, GetTypeName(expr.Type))  
                        Case 1  
                            Return Expression.[Call](expr, DirectCast(mb, MethodInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousIndexerInvocation, GetTypeName(expr.Type))  
                    End Select  
                End If  
            End Function  
     
            Private Shared Function IsPredefinedType(ByVal type As Type) As Boolean  
                For Each t As Type In predefinedTypes  
                    If t Is type Then  
                        Return True  
                    End If  
                Next  
                Return False  
            End Function  
     
            Private Shared Function IsNullableType(ByVal type As Type) As Boolean  
                Return type.IsGenericType AndAlso type.GetGenericTypeDefinition() Is GetType(Nullable(Of ))  
            End Function  
     
            Private Shared Function GetNonNullableType(ByVal type As Type) As Type  
                Return If(IsNullableType(type), type.GetGenericArguments()(0), type)  
            End Function  
     
            Private Shared Function GetTypeName(ByVal type As Type) As String  
                Dim baseType As Type = GetNonNullableType(type)  
                Dim s As String = baseType.Name  
                If type IsNot baseType Then  
                    s += "?"c  
                End If  
                Return s  
            End Function  
     
            Private Shared Function IsNumericType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) <> 0  
            End Function  
     
            Private Shared Function IsSignedIntegralType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) = 2  
            End Function  
     
            Private Shared Function IsUnsignedIntegralType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) = 3  
            End Function  
     
            Private Shared Function GetNumericTypeKind(ByVal type__1 As Type) As Integer  
                type__1 = GetNonNullableType(type__1)  
                If type__1.IsEnum Then  
                    Return 0  
                End If  
                Select Case Type.GetTypeCode(type__1)  
                    Case TypeCode.[Char], TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                        Return 1  
                    Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64  
                        Return 2  
                    Case TypeCode.[Byte], TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64  
                        Return 3  
                    Case Else  
                        Return 0  
                End Select  
            End Function  
     
            Private Shared Function IsEnumType(ByVal type As Type) As Boolean  
                Return GetNonNullableType(type).IsEnum  
            End Function  
     
            Private Sub CheckAndPromoteOperand(ByVal signatures As Type, ByVal opName As String, ByRef expr As Expression, ByVal errorPos As Integer)  
                Dim args As Expression() = New Expression() {expr}  
                Dim method As MethodBase  
                If FindMethod(signatures, "F", False, args, method) <> 1 Then  
                    Throw ParseError(errorPos, Res.IncompatibleOperand, opName, GetTypeName(args(0).Type))  
                End If  
                expr = args(0)  
            End Sub  
     
            Private Sub CheckAndPromoteOperands(ByVal signatures As Type, ByVal opName As String, ByRef left As Expression, ByRef right As Expression, ByVal errorPos As Integer)  
                Dim args As Expression() = New Expression() {left, right}  
                Dim method As MethodBase  
                If FindMethod(signatures, "F", False, args, method) <> 1 Then  
                    Throw IncompatibleOperandsError(opName, left, right, errorPos)  
                End If  
                left = args(0)  
                right = args(1)  
            End Sub  
     
            Private Function IncompatibleOperandsError(ByVal opName As String, ByVal left As Expression, ByVal right As Expression, ByVal pos As Integer) As Exception  
                Return ParseError(pos, Res.IncompatibleOperands, opName, GetTypeName(left.Type), GetTypeName(right.Type))  
            End Function  
     
            Private Function FindPropertyOrField(ByVal type__1 As Type, ByVal memberName As String, ByVal staticAccess As Boolean) As MemberInfo  
                Dim flags As BindingFlagsBindingFlags = BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or (If(staticAccess, BindingFlags.[Static], BindingFlags.Instance))  
                For Each t As Type In SelfAndBaseTypes(type__1)  
                    Dim members As MemberInfo() = t.FindMembers(MemberTypes.[Property] Or MemberTypes.Field, flags, Type.FilterNameIgnoreCase, memberName)  
                    If members.Length <> 0 Then  
                        Return members(0)  
                    End If  
                Next  
                Return Nothing  
            End Function  
     
            Private Function FindMethod(ByVal type__1 As Type, ByVal methodName As String, ByVal staticAccess As Boolean, ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                Dim flags As BindingFlagsBindingFlags = BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or (If(staticAccess, BindingFlags.[Static], BindingFlags.Instance))  
                For Each t As Type In SelfAndBaseTypes(type__1)  
                    Dim members As MemberInfo() = t.FindMembers(MemberTypes.Method, flags, Type.FilterNameIgnoreCase, methodName)  
                    Dim count As Integer = FindBestMethod(members.Cast(Of MethodBase)(), args, method)  
                    If count <> 0 Then  
                        Return count  
                    End If  
                Next  
                method = Nothing 
                Return 0  
            End Function  
     
            Private Function FindIndexer(ByVal type As Type, ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                For Each t As Type In SelfAndBaseTypes(type)  
                    Dim members As MemberInfo() = t.GetDefaultMembers()  
                    If members.Length <> 0 Then  
                        Dim methods As IEnumerable(Of MethodBase) = members.OfType(Of PropertyInfo)().[Select](Function(p) DirectCast(p.GetGetMethod(), MethodBase)).Where(Function(m) m IsNot Nothing)  
                        Dim count As Integer = FindBestMethod(methods, args, method)  
                        If count <> 0 Then  
                            Return count  
                        End If  
                    End If  
                Next  
                method = Nothing 
                Return 0  
            End Function  
     
            Private Shared Function SelfAndBaseTypes(ByVal type As Type) As IEnumerable(Of Type)  
                If type.IsInterface Then  
                    Dim types As New List(Of Type)()  
                    AddInterface(types, type)  
                    Return types  
                End If  
                Return SelfAndBaseClasses(type)  
            End Function  
     
            Private Shared Function SelfAndBaseClasses(ByVal type As Type) As IEnumerable(Of Type)  
                While type IsNot Nothing  
                    Return New Type() {type}  
                    typetype = type.BaseType  
                End While  
            End Function  
     
            Private Shared Sub AddInterface(ByVal types As List(Of Type), ByVal type As Type)  
                If Not types.Contains(type) Then  
                    types.Add(type)  
                    For Each t As Type In type.GetInterfaces()  
                        AddInterface(types, t)  
                    Next  
                End If  
            End Sub  
     
            Private Class MethodData  
                Public MethodBase As MethodBase  
                Public Parameters As ParameterInfo()  
                Public Args As Expression()  
            End Class  
     
            Private Function FindBestMethod(ByVal methods As IEnumerable(Of MethodBase), ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                Dim applicable As MethodData() = methods.[Select](Function(m) New MethodData() With { _  
                  .MethodBase = m, _  
                  .Parameters = m.GetParameters() _  
                }).Where(Function(m) IsApplicable(m, args)).ToArray()  
                If applicable.Length > 1 Then  
                    applicableapplicable = applicable.Where(Function(m) applicable.All(Function(n) m.Equals(n) OrElse IsBetterThan(args, m, n))).ToArray()  
                End If  
                If applicable.Length = 1 Then  
                    Dim md As MethodData = applicable(0)  
                    For i As Integer = 0 To args.Length - 1  
                        args(i) = md.Args(i)  
                    Next  
                    method = md.MethodBase  
                Else  
                    method = Nothing 
                End If  
                Return applicable.Length  
            End Function  
     
            Private Function IsApplicable(ByVal method As MethodData, ByVal args As Expression()) As Boolean  
                If method.Parameters.Length <> args.Length Then  
                    Return False  
                End If  
                Dim promotedArgs As Expression() = New Expression(args.Length - 1) {}  
                For i As Integer = 0 To args.Length - 1  
                    Dim pi As ParameterInfo = method.Parameters(i)  
                    If pi.IsOut Then  
                        Return False  
                    End If  
                    Dim promoted As Expression = PromoteExpression(args(i), pi.ParameterType, False)  
                    If promoted Is Nothing Then  
                        Return False  
                    End If  
                    promotedArgs(i) = promoted  
                Next  
                method.Args = promotedArgs 
                Return True  
            End Function  
     
            Private Function PromoteExpression(ByVal expr As Expression, ByVal type__1 As Type, ByVal exact As Boolean) As Expression  
                If expr.Type.Equals(type__1) Then  
                    Return expr  
                End If  
                If TypeOf expr Is ConstantExpression Then  
                    Dim ce As ConstantExpression = DirectCast(expr, ConstantExpression)  
                    If ce.Equals(nullLiteral) Then  
                        If Not type__1.IsValueType OrElse IsNullableType(type__1) Then  
                            Return Expression.Constant(Nothing, type__1)  
                        End If  
                    Else  
                        Dim text As String  
                        If literals.TryGetValue(ce, text) Then  
                            Dim target As Type = GetNonNullableType(type__1)  
                            Dim value As [Object] = Nothing  
                            Select Case Type.GetTypeCode(ce.Type)  
                                Case TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64  
                                    value = ParseNumber(text, target)  
                                    Exit Select  
                                Case TypeCode.[Double]  
                                    If target Is GetType(Decimal) Then  
                                        value = ParseNumber(text, target)  
                                    End If  
                                    Exit Select  
                                Case TypeCode.[String]  
                                    value = ParseEnum(text, target)  
                                    Exit Select  
                            End Select  
                            If value IsNot Nothing Then  
                                Return Expression.Constant(value, type__1)  
                            End If  
                        End If  
                    End If  
                End If  
                If IsCompatibleWith(expr.Type, type__1) Then  
                    If type__1.IsValueType OrElse exact Then  
                        Return Expression.Convert(expr, type__1)  
                    End If  
                    Return expr  
                End If  
                Return Nothing  
            End Function  
     
            Private Shared Function ParseNumber(ByVal text As String, ByVal type__1 As Type) As Object  
                Select Case Type.GetTypeCode(GetNonNullableType(type__1))  
                    Case TypeCode.[SByte]  
                        Dim sb As SByte  
                        If SByte.TryParse(text, sb) Then  
                            Return sb  
                        End If  
                        Exit Select  
                    Case TypeCode.[Byte]  
                        Dim b As Byte  
                        If Byte.TryParse(text, b) Then  
                            Return b  
                        End If  
                        Exit Select  
                    Case TypeCode.Int16  
                        Dim s As Short  
                        If Short.TryParse(text, s) Then  
                            Return s  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt16  
                        Dim us As UShort  
                        If UShort.TryParse(text, us) Then  
                            Return us  
                        End If  
                        Exit Select  
                    Case TypeCode.Int32  
                        Dim i As Integer  
                        If Integer.TryParse(text, i) Then  
                            Return i  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt32  
                        Dim ui As UInteger  
                        If UInteger.TryParse(text, ui) Then  
                            Return ui  
                        End If  
                        Exit Select  
                    Case TypeCode.Int64  
                        Dim l As Long  
                        If Long.TryParse(text, l) Then  
                            Return l  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt64  
                        Dim ul As ULong  
                        If ULong.TryParse(text, ul) Then  
                            Return ul  
                        End If  
                        Exit Select  
                    Case TypeCode.[Single]  
                        Dim f As Single  
                        If Single.TryParse(text, f) Then  
                            Return f  
                        End If  
                        Exit Select  
                    Case TypeCode.[Double]  
                        Dim d As Double  
                        If Double.TryParse(text, d) Then  
                            Return d  
                        End If  
                        Exit Select  
                    Case TypeCode.[Decimal]  
                        Dim e As Decimal  
                        If Decimal.TryParse(text, e) Then  
                            Return e  
                        End If  
                        Exit Select  
                End Select  
                Return Nothing  
            End Function  
     
            Private Shared Function ParseEnum(ByVal name As String, ByVal type__1 As Type) As Object  
                If type__1.IsEnum Then  
                    Dim memberInfos As MemberInfo() = type__1.FindMembers(MemberTypes.Field, BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or BindingFlags.[Static], Type.FilterNameIgnoreCase, name)  
                    If memberInfos.Length <> 0 Then  
                        Return DirectCast(memberInfos(0), FieldInfo).GetValue(Nothing)  
                    End If  
                End If  
                Return Nothing  
            End Function  
     
            Private Shared Function IsCompatibleWith(ByVal source As Type, ByVal target As Type) As Boolean  
                If source Is target Then  
                    Return True  
                End If  
                If Not target.IsValueType Then  
                    Return target.IsAssignableFrom(source)  
                End If  
                Dim st As Type = GetNonNullableType(source)  
                Dim tt As Type = GetNonNullableType(target)  
                If st IsNot source AndAlso tt Is target Then  
                    Return False  
                End If  
                Dim sc As TypeCode = If(st.IsEnum, TypeCode.[Object], Type.GetTypeCode(st))  
                Dim tc As TypeCode = If(tt.IsEnum, TypeCode.[Object], Type.GetTypeCode(tt))  
                Select Case sc  
                    Case TypeCode.[SByte]  
                        Select Case tc  
                            Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], _  
                             TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.[Byte]  
                        Select Case tc  
                            Case TypeCode.[Byte], TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, _  
                             TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int16  
                        Select Case tc  
                            Case TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt16  
                        Select Case tc  
                            Case TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.[Single], _  
                             TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int32  
                        Select Case tc  
                            Case TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt32  
                        Select Case tc  
                            Case TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int64  
                        Select Case tc  
                            Case TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt64  
                        Select Case tc  
                            Case TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.[Single]  
                        Select Case tc  
                            Case TypeCode.[Single], TypeCode.[Double]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case Else  
                        If st Is tt Then  
                            Return True  
                        End If  
                        Exit Select  
                End Select  
                Return False  
            End Function  
     
            Private Shared Function IsBetterThan(ByVal args As Expression(), ByVal m1 As MethodData, ByVal m2 As MethodData) As Boolean  
                Dim better As Boolean = False 
                For i As Integer = 0 To args.Length - 1  
                    Dim c As Integer = CompareConversions(args(i).Type, m1.Parameters(i).ParameterType, m2.Parameters(i).ParameterType)  
                    If c < 0 Then  
                        Return False  
                    End If  
                    If c > 0 Then  
                        better = True 
                    End If  
                Next  
                Return better  
            End Function  
     
            ' Return 1 if s -> t1 is a better conversion than s -> t2  
            ' Return -1 if s -> t2 is a better conversion than s -> t1  
            ' Return 0 if neither conversion is better  
            Private Shared Function CompareConversions(ByVal s As Type, ByVal t1 As Type, ByVal t2 As Type) As Integer  
                If t1 Is t2 Then  
                    Return 0  
                End If  
                If s Is t1 Then  
                    Return 1  
                End If  
                If s Is t2 Then  
                    Return -1  
                End If  
                Dim t1t2 As Boolean = IsCompatibleWith(t1, t2)  
                Dim t2t1 As Boolean = IsCompatibleWith(t2, t1)  
                If t1t2 AndAlso Not t2t1 Then  
                    Return 1  
                End If  
                If t2t1 AndAlso Not t1t2 Then  
                    Return -1  
                End If  
                If IsSignedIntegralType(t1) AndAlso IsUnsignedIntegralType(t2) Then  
                    Return 1  
                End If  
                If IsSignedIntegralType(t2) AndAlso IsUnsignedIntegralType(t1) Then  
                    Return -1  
                End If  
                Return 0  
            End Function  
     
            Private Function GenerateEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.Equal(left, right)  
            End Function  
     
            Private Function GenerateNotEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.NotEqual(left, right)  
            End Function  
     
            Private Function GenerateGreaterThan(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.GreaterThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.GreaterThan(left, right)  
            End Function  
     
            Private Function GenerateGreaterThanEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.GreaterThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.GreaterThanOrEqual(left, right)  
            End Function  
     
            Private Function GenerateLessThan(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.LessThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.LessThan(left, right)  
            End Function  
     
            Private Function GenerateLessThanEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.LessThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.LessThanOrEqual(left, right)  
            End Function  
     
            Private Function GenerateAdd(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) AndAlso right.Type.Equals(GetType(String)) Then  
                    Return GenerateStaticMethodCall("Concat", left, right)  
                End If  
                Return Expression.Add(left, right)  
            End Function  
     
            Private Function GenerateSubtract(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.Subtract(left, right)  
            End Function  
     
            Private Function GenerateStringConcat(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.[Call](Nothing, GetType(String).GetMethod("Concat", New Object() {GetType(Object), GetType(Object)}), New Object() {left, right})  
            End Function  
     
            Private Function GetStaticMethod(ByVal methodName As String, ByVal left As Expression, ByVal right As Expression) As MethodInfo  
                Return left.Type.GetMethod(methodName, New Object() {left.Type, right.Type})  
            End Function  
     
            Private Function GenerateStaticMethodCall(ByVal methodName As String, ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.[Call](Nothing, GetStaticMethod(methodName, left, right), New Object() {left, right})  
            End Function  
     
            Private Sub SetTextPos(ByVal pos As Integer)  
                textPos = pos 
                ch = If(textPos < textLen, text(textPos), ControlChars.NullChar)  
            End Sub  
     
            Private Sub NextChar()  
                If textPos < textLen Then  
                    textPos += 1  
                End If  
                ch = If(textPos < textLen, text(textPos), ControlChars.NullChar)  
            End Sub  
     
            Private Sub NextToken()  
                While [Char].IsWhiteSpace(ch)  
                    NextChar()  
                End While  
                Dim t As TokenId  
                Dim tokenPos As Integer = textPos 
                Select Case ch  
                    Case "!"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.ExclamationEqual  
                        Else  
                            t = TokenId.Exclamation  
                        End If  
                        Exit Select  
                    Case "%"c  
                        NextChar()  
                        t = TokenId.Percent  
                        Exit Select  
                    Case "&"c  
                        NextChar()  
                        If cch = "&"c Then  
                            NextChar()  
                            t = TokenId.DoubleAmphersand  
                        Else  
                            t = TokenId.Amphersand  
                        End If  
                        Exit Select  
                    Case "("c  
                        NextChar()  
                        t = TokenId.OpenParen  
                        Exit Select  
                    Case ")"c  
                        NextChar()  
                        t = TokenId.CloseParen  
                        Exit Select  
                    Case "*"c  
                        NextChar()  
                        t = TokenId.Asterisk  
                        Exit Select  
                    Case "+"c  
                        NextChar()  
                        t = TokenId.Plus  
                        Exit Select  
                    Case ","c  
                        NextChar()  
                        t = TokenId.Comma  
                        Exit Select  
                    Case "-"c  
                        NextChar()  
                        t = TokenId.Minus  
                        Exit Select  
                    Case "."c  
                        NextChar()  
                        t = TokenId.Dot  
                        Exit Select  
                    Case "/"c  
                        NextChar()  
                        t = TokenId.Slash  
                        Exit Select  
                    Case ":"c  
                        NextChar()  
                        t = TokenId.Colon  
                        Exit Select  
                    Case "<"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.LessThanEqual  
                        ElseIf cch = ">"c Then  
                            NextChar()  
                            t = TokenId.LessGreater  
                        Else  
                            t = TokenId.LessThan  
                        End If  
                        Exit Select  
                    Case "="c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.DoubleEqual  
                        Else  
                            t = TokenId.Equal  
                        End If  
                        Exit Select  
                    Case ">"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.GreaterThanEqual  
                        Else  
                            t = TokenId.GreaterThan  
                        End If  
                        Exit Select  
                    Case "?"c  
                        NextChar()  
                        t = TokenId.Question  
                        Exit Select  
                    Case "["c  
                        NextChar()  
                        t = TokenId.OpenBracket  
                        Exit Select  
                    Case "]"c  
                        NextChar()  
                        t = TokenId.CloseBracket  
                        Exit Select  
                    Case "|"c  
                        NextChar()  
                        If cch = "|"c Then  
                            NextChar()  
                            t = TokenId.DoubleBar  
                        Else  
                            t = TokenId.Bar  
                        End If  
                        Exit Select  
                    Case """"c, "'"c  
                        Dim quote As Char = ch 
                        Do  
                            NextChar()  
                            While textPos < textLen AndAlso ch <> quote  
                                NextChar()  
                            End While  
                            If textPos = textLen Then  
                                Throw ParseError(textPos, Res.UnterminatedStringLiteral)  
                            End If  
                            NextChar()  
                        Loop While ch = quote 
                        t = TokenId.StringLiteral  
                        Exit Select  
                    Case Else  
                        If [Char].IsLetter(ch) OrElse cch = "@"c OrElse cch = "_"c Then  
                            Do  
                                NextChar()  
                            Loop While [Char].IsLetterOrDigit(ch) OrElse cch = "_"c  
                            t = TokenId.Identifier  
                            Exit Select  
                        End If  
                        If [Char].IsDigit(ch) Then  
                            t = TokenId.IntegerLiteral  
                            Do  
                                NextChar()  
                            Loop While [Char].IsDigit(ch)  
                            If cch = "."c Then  
                                t = TokenId.RealLiteral  
                                NextChar()  
                                ValidateDigit()  
                                Do  
                                    NextChar()  
                                Loop While [Char].IsDigit(ch)  
                            End If  
                            If cch = "E"c OrElse cch = "e"c Then  
                                t = TokenId.RealLiteral  
                                NextChar()  
                                If cch = "+"c OrElse cch = "-"c Then  
                                    NextChar()  
                                End If  
                                ValidateDigit()  
                                Do  
                                    NextChar()  
                                Loop While [Char].IsDigit(ch)  
                            End If  
                            If cch = "F"c OrElse cch = "f"c Then  
                                NextChar()  
                            End If  
                            Exit Select  
                        End If  
                        If textPos = textLen Then  
                            t = TokenId.[End]  
                            Exit Select  
                        End If  
                        Throw ParseError(textPos, Res.InvalidCharacter, ch)  
                End Select  
                varToken.id = t 
                varToken.text = text.Substring(tokenPos, textPos - tokenPos)  
                varToken.pos = tokenPos 
            End Sub  
     
            Private Function TokenIdentifierIs(ByVal id As String) As Boolean  
                Return varToken.id = TokenId.Identifier AndAlso [String].Equals(id, varToken.text, StringComparison.OrdinalIgnoreCase)  
            End Function  
     
            Private Function GetIdentifier() As String  
                ValidateToken(TokenId.Identifier, Res.IdentifierExpected)  
                Dim id As String = varToken.text  
                If id.Length > 1 AndAlso id(0) = "@"c Then  
                    idid = id.Substring(1)  
                End If  
                Return id  
            End Function  
     
            Private Sub ValidateDigit()  
                If Not [Char].IsDigit(ch) Then  
                    Throw ParseError(textPos, Res.DigitExpected)  
                End If  
            End Sub  
     
            Private Sub ValidateToken(ByVal t As TokenId, ByVal errorMessage As String)  
                If varToken.id <> t Then  
                    Throw ParseError(errorMessage)  
                End If  
            End Sub  
     
            Private Sub ValidateToken(ByVal t As TokenId)  
                If varToken.id <> t Then  
                    Throw ParseError(Res.SyntaxError)  
                End If  
            End Sub  
     
            Private Function ParseError(ByVal format As String, ByVal ParamArray args As Object()) As Exception  
                Return ParseError(varToken.pos, format, args)  
            End Function  
     
            Private Function ParseError(ByVal pos As Integer, ByVal format As String, ByVal ParamArray args As Object()) As Exception  
                Return New ParseException(String.Format(Globalization.CultureInfo.CurrentCulture, format, args), pos)  
            End Function  
     
            Private Shared Function CreateKeywords() As Dictionary(Of String, Object)  
                Dim d As New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)  
                d.Add("true", trueLiteral)  
                d.Add("false", falseLiteral)  
                d.Add("null", nullLiteral)  
                d.Add(keywordIt, keywordIt)  
                d.Add(keywordIif, keywordIif)  
                d.Add(keywordNew, keywordNew)  
                For Each type As Type In predefinedTypes  
                    d.Add(type.Name, type)  
                Next  
                Return d  
            End Function  
            Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T  
                target = value 
                Return value  
            End Function  
        End Class  
     
        NotInheritable Class Res  
            Private Sub New()  
            End Sub  
            Public Const DuplicateIdentifier As String = "The identifier '{0}' was defined more than once" 
            Public Const ExpressionTypeMismatch As String = "Expression of type '{0}' expected" 
            Public Const ExpressionExpected As String = "Expression expected" 
            Public Const InvalidCharacterLiteral As String = "Character literal must contain exactly one character" 
            Public Const InvalidIntegerLiteral As String = "Invalid integer literal '{0}'" 
            Public Const InvalidRealLiteral As String = "Invalid real literal '{0}'" 
            Public Const UnknownIdentifier As String = "Unknown identifier '{0}'" 
            Public Const NoItInScope As String = "No 'it' is in scope" 
            Public Const IifRequiresThreeArgs As String = "The 'iif' function requires three arguments" 
            Public Const FirstExprMustBeBool As String = "The first expression must be of type 'Boolean'" 
            Public Const BothTypesConvertToOther As String = "Both of the types '{0}' and '{1}' convert to the other" 
            Public Const NeitherTypeConvertsToOther As String = "Neither of the types '{0}' and '{1}' converts to the other" 
            Public Const MissingAsClause As String = "Expression is missing an 'as' clause" 
            Public Const ArgsIncompatibleWithLambda As String = "Argument list incompatible with lambda expression" 
            Public Const TypeHasNoNullableForm As String = "Type '{0}' has no nullable form" 
            Public Const NoMatchingConstructor As String = "No matching constructor in type '{0}'" 
            Public Const AmbiguousConstructorInvocation As String = "Ambiguous invocation of '{0}' constructor" 
            Public Const CannotConvertValue As String = "A value of type '{0}' cannot be converted to type '{1}'" 
            Public Const NoApplicableMethod As String = "No applicable method '{0}' exists in type '{1}'" 
            Public Const MethodsAreInaccessible As String = "Methods on type '{0}' are not accessible" 
            Public Const MethodIsVoid As String = "Method '{0}' in type '{1}' does not return a value" 
            Public Const AmbiguousMethodInvocation As String = "Ambiguous invocation of method '{0}' in type '{1}'" 
            Public Const UnknownPropertyOrField As String = "No property or field '{0}' exists in type '{1}'" 
            Public Const NoApplicableAggregate As String = "No applicable aggregate method '{0}' exists" 
            Public Const CannotIndexMultiDimArray As String = "Indexing of multi-dimensional arrays is not supported" 
            Public Const InvalidIndex As String = "Array index must be an integer expression" 
            Public Const NoApplicableIndexer As String = "No applicable indexer exists in type '{0}'" 
            Public Const AmbiguousIndexerInvocation As String = "Ambiguous invocation of indexer in type '{0}'" 
            Public Const IncompatibleOperand As String = "Operator '{0}' incompatible with operand type '{1}'" 
            Public Const IncompatibleOperands As String = "Operator '{0}' incompatible with operand types '{1}' and '{2}'" 
            Public Const UnterminatedStringLiteral As String = "Unterminated string literal" 
            Public Const InvalidCharacter As String = "Syntax error '{0}'" 
            Public Const DigitExpected As String = "Digit expected" 
            Public Const SyntaxError As String = "Syntax error" 
            Public Const TokenExpected As String = "{0} expected" 
            Public Const ParseExceptionFormat As String = "{0} (at index {1})" 
            Public Const ColonExpected As String = "':' expected" 
            Public Const OpenParenExpected As String = "'(' expected" 
            Public Const CloseParenOrOperatorExpected As String = "')' or operator expected" 
            Public Const CloseParenOrCommaExpected As String = "')' or ',' expected" 
            Public Const DotOrOpenParenExpected As String = "'.' or '(' expected" 
            Public Const OpenBracketExpected As String = "'[' expected" 
            Public Const CloseBracketOrCommaExpected As String = "']' or ',' expected" 
            Public Const IdentifierExpected As String = "Identifier expected" 
        End Class  
    End Namespace 

  • Sam 13 Oct 2010
    ''Copyright (C) Microsoft Corporation.  All rights reserved.  
     
    Imports System.Collections.Generic  
    Imports System.Text  
    Imports System.Linq  
    Imports System.Linq.Expressions  
    Imports System.Reflection  
    Imports System.Reflection.Emit  
    Imports System.Threading  
    Imports System.Dynamic  
    Imports System.Runtime.CompilerServices  
     
    Namespace SQLWiz.Dynamic  
        Module DynamicQueryable  
            Sub New()  
            End Sub  
            <Extension()> _  
            Public Function Where(Of T)(ByVal source As IQueryable(Of T), ByVal predicate As String, ByVal ParamArray values As Object()) As IQueryable(Of T)  
                Return DirectCast(Where(DirectCast(source, IQueryable), predicate, values), IQueryable(Of T))  
            End Function  
     
            <Extension()> _  
            Public Function Where(ByVal source As IQueryable, ByVal predicate As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If predicate Is Nothing Then  
                    Throw New ArgumentNullException("predicate")  
                End If  
                Dim lambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, GetType(Boolean), predicate, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Where", New Type() {source.ElementType}, source.Expression, Expression.Quote(lambda)))  
            End Function  
     
            <Extension()> _  
            Public Function [Select](ByVal source As IQueryable, ByVal selector As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If selector Is Nothing Then  
                    Throw New ArgumentNullException("selector")  
                End If  
                Dim lambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, selector, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Select", New Type() {source.ElementType, lambda.Body.Type}, source.Expression, Expression.Quote(lambda)))  
            End Function  
     
            <Extension()> _  
            Public Function OrderBy(Of T)(ByVal source As IQueryable(Of T), ByVal ordering As String, ByVal ParamArray values As Object()) As IQueryable(Of T)  
                Return DirectCast(OrderBy(DirectCast(source, IQueryable), ordering, values), IQueryable(Of T))  
            End Function  
     
            <Extension()> _  
            Public Function OrderBy(ByVal source As IQueryable, ByVal ordering As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If ordering Is Nothing Then  
                    Throw New ArgumentNullException("ordering")  
                End If  
                Dim parameters As ParameterExpression() = New ParameterExpression() {Expression.Parameter(source.ElementType, "")}  
                Dim parser As New ExpressionParser(parameters, ordering, values)  
                Dim orderings As IEnumerable(Of DynamicOrdering) = parser.ParseOrdering()  
                Dim queryExpr As Expression = source.Expression  
                Dim methodAsc As String = "OrderBy" 
                Dim methodDesc As String = "OrderByDescending" 
                For Each o As DynamicOrdering In orderings  
                    queryExpr = Expression.[Call](GetType(Queryable), If(o.Ascending, methodAsc, methodDesc), New Type() {source.ElementType, o.Selector.Type}, queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)))  
                    methodAsc = "ThenBy" 
                    methodDesc = "ThenByDescending" 
                Next  
                Return source.Provider.CreateQuery(queryExpr)  
            End Function  
     
            <Extension()> _  
            Public Function Take(ByVal source As IQueryable, ByVal count As Integer) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Take", New Type() {source.ElementType}, source.Expression, Expression.Constant(count)))  
            End Function  
     
            <Extension()> _  
            Public Function Skip(ByVal source As IQueryable, ByVal count As Integer) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Skip", New Type() {source.ElementType}, source.Expression, Expression.Constant(count)))  
            End Function  
     
            <Extension()> _  
            Public Function GroupBy(ByVal source As IQueryable, ByVal keySelector As String, ByVal elementSelector As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If keySelector Is Nothing Then  
                    Throw New ArgumentNullException("keySelector")  
                End If  
                If elementSelector Is Nothing Then  
                    Throw New ArgumentNullException("elementSelector")  
                End If  
                Dim keyLambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, keySelector, values)  
                Dim elementLambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, elementSelector, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "GroupBy", New Type() {source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type}, source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda)))  
            End Function  
     
            <Extension()> _  
            Public Function Any(ByVal source As IQueryable) As Boolean  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return CBool(source.Provider.Execute(Expression.[Call](GetType(Queryable), "Any", New Type() {source.ElementType}, source.Expression)))  
            End Function  
     
            <Extension()> _  
            Public Function Count(ByVal source As IQueryable) As Integer  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return CInt(source.Provider.Execute(Expression.[Call](GetType(Queryable), "Count", New Type() {source.ElementType}, source.Expression)))  
            End Function  
        End Module  
     
        Public MustInherit Class DynamicClass  
            Public Overrides Function ToString() As String  
                Dim props As PropertyInfo() = Me.[GetType]().GetProperties(BindingFlags.Instance Or BindingFlags.[Public])  
                Dim sb As New StringBuilder()  
                sb.Append("{")  
                For i As Integer = 0 To props.Length - 1  
                    If i > 0 Then  
                        sb.Append(", ")  
                    End If  
                    sb.Append(props(i).Name)  
                    sb.Append("=")  
                    sb.Append(props(i).GetValue(Me, Nothing))  
                Next  
                sb.Append("}")  
                Return sb.ToString()  
            End Function  
        End Class  
     
        Public Class DynamicProperty  
            Private m_name As String  
            Private m_type As Type  
     
            Public Sub New(ByVal name As String, ByVal type As Type)  
                If name Is Nothing Then  
                    Throw New ArgumentNullException("name")  
                End If  
                If type Is Nothing Then  
                    Throw New ArgumentNullException("type")  
                End If  
                Me.m_name = name  
                Me.m_type = type  
            End Sub  
     
            Public ReadOnly Property Name() As String  
                Get  
                    Return m_name  
                End Get  
            End Property  
     
            Public ReadOnly Property Type() As Type  
                Get  
                    Return m_type  
                End Get  
            End Property  
        End Class  
     
        Module DynamicExpression  
            Sub New()  
            End Sub  
            Public Function Parse(ByVal resultType As Type, ByVal expression As String, ByVal ParamArray values As Object()) As Expression  
                Dim parser As New ExpressionParser(Nothing, expression, values)  
                Return parser.Parse(resultType)  
            End Function  
     
            Public Function ParseLambda(ByVal itType As Type, ByVal resultType As Type, ByVal expression__1 As String, ByVal ParamArray values As Object()) As LambdaExpression  
                Return ParseLambda(New ParameterExpression() {Expression.Parameter(itType, "")}, resultType, expression__1, values)  
            End Function  
     
            Public Function ParseLambda(ByVal parameters As ParameterExpression(), ByVal resultType As Type, ByVal expression__1 As String, ByVal ParamArray values As Object()) As LambdaExpression  
                Dim parser As New ExpressionParser(parameters, expression__1, values)  
                Return Expression.Lambda(parser.Parse(resultType), parameters)  
            End Function  
     
            Public Function ParseLambda(Of T, S)(ByVal expression As String, ByVal ParamArray values As Object()) As Expression(Of Func(Of T, S))  
                Return DirectCast(ParseLambda(GetType(T), GetType(S), expression, values), Expression(Of Func(Of T, S)))  
            End Function  
     
            Public Function CreateClass(ByVal ParamArray properties As DynamicProperty()) As Type  
                Return ClassFactory.Instance.GetDynamicClass(properties)  
            End Function  
     
            Public Function CreateClass(ByVal properties As IEnumerable(Of DynamicProperty)) As Type  
                Return ClassFactory.Instance.GetDynamicClass(properties)  
            End Function  
        End Module  
     
        Friend Class DynamicOrdering  
            Public Selector As Expression  
            Public Ascending As Boolean  
        End Class  
     
        Friend Class Signature  
            Implements IEquatable(Of Signature)  
            Public properties As DynamicProperty()  
            Public hashCode As Integer  
     
            Public Sub New(ByVal properties As IEnumerable(Of DynamicProperty))  
                Me.properties = properties.ToArray()  
                hashCode = 0 
                For Each p As DynamicProperty In properties  
                    hashCodehashCode = hashCode Xor p.Name.GetHashCode() Xor p.Type.GetHashCode()  
                Next  
            End Sub  
     
            Public Overrides Function GetHashCode() As Integer  
                Return hashCode  
            End Function  
     
            Public Overrides Function Equals(ByVal obj As Object) As Boolean  
                Return If(TypeOf obj Is Signature, Equals(DirectCast(obj, Signature)), False)  
            End Function  
     
            Public Overloads Function Equals(ByVal other As Signature) As Boolean Implements IEquatable(Of Signature).Equals  
                If properties.Length <> other.properties.Length Then  
                    Return False  
                End If  
                For i As Integer = 0 To properties.Length - 1  
                    If properties(i).Name <> other.properties(i).Name OrElse properties(i).Type IsNot other.properties(i).Type Then  
                        Return False  
                    End If  
                Next  
                Return True  
            End Function  
        End Class  
     
        Friend Class ClassFactory  
            Public Shared ReadOnly Instance As New ClassFactory()  
     
            Shared Sub New()  
            End Sub  
            ' Trigger lazy initialization of static fields  
            Private [module] As ModuleBuilder  
            Private classes As Dictionary(Of Signature, Type)  
            Private classCount As Integer  
     
            Private Sub New()  
                Dim name As New AssemblyName("DynamicClasses")  
                Dim assembly As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run)  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                    New ReflectionPermission(PermissionState.Unrestricted).Assert()  
    #End If  
                Try  
                    [module] = assembly.DefineDynamicModule("Module")  
                Finally  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                    PermissionSet.RevertAssert()  
    #End If  
                End Try  
                classes = New Dictionary(Of Signature, Type)()  
            End Sub  
     
            Public Function GetDynamicClass(ByVal properties As IEnumerable(Of DynamicProperty)) As Type  
                Try  
                    Dim signature As New Signature(properties)  
                    Dim type As Type  
                    If Not classes.TryGetValue(signature, type) Then  
                        type = CreateDynamicClass(signature.properties)  
                        classes.Add(signature, type)  
                    End If  
                    Return type  
                Finally  
                End Try  
            End Function  
     
            Private Function CreateDynamicClass(ByVal properties As DynamicProperty()) As Type  
                Try  
                    Dim typeName As String = "DynamicClass" & (classCount + 1)  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                        New ReflectionPermission(PermissionState.Unrestricted).Assert()  
    #End If  
                    Try  
                        Dim tb As TypeBuilder = Me.[module].DefineType(typeName, TypeAttributes.[Class] Or TypeAttributes.[Public], GetType(DynamicClass))  
                        Dim fields As FieldInfo() = GenerateProperties(tb, properties)  
                        GenerateEquals(tb, fields)  
                        GenerateGetHashCode(tb, fields)  
                        Dim result As Type = tb.CreateType()  
                        classCount += 1  
                        Return result  
                    Finally  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                        PermissionSet.RevertAssert()  
    #End If  
                    End Try  
                Finally  
                End Try  
            End Function  
     
            Private Function GenerateProperties(ByVal tb As TypeBuilder, ByVal properties As DynamicProperty()) As FieldInfo()  
                Dim fields As FieldInfo() = New FieldBuilder(properties.Length - 1) {}  
                For i As Integer = 0 To properties.Length - 1  
                    Dim dp As DynamicProperty = properties(i)  
                    Dim fb As FieldBuilder = tb.DefineField("_" & dp.Name, dp.Type, FieldAttributes.[Private])  
                    Dim pb As PropertyBuilder = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, Nothing)  
                    Dim mbGet As MethodBuilder = tb.DefineMethod("get_" & dp.Name, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, dp.Type, Type.EmptyTypes)  
                    Dim genGet As ILGenerator = mbGet.GetILGenerator()  
                    genGet.Emit(OpCodes.Ldarg_0)  
                    genGet.Emit(OpCodes.Ldfld, fb)  
                    genGet.Emit(OpCodes.Ret)  
                    Dim mbSet As MethodBuilder = tb.DefineMethod("set_" & dp.Name, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, Nothing, New Type() {dp.Type})  
                    Dim genSet As ILGenerator = mbSet.GetILGenerator()  
                    genSet.Emit(OpCodes.Ldarg_0)  
                    genSet.Emit(OpCodes.Ldarg_1)  
                    genSet.Emit(OpCodes.Stfld, fb)  
                    genSet.Emit(OpCodes.Ret)  
                    pb.SetGetMethod(mbGet)  
                    pb.SetSetMethod(mbSet)  
                    fields(i) = fb  
                Next  
                Return fields  
            End Function  
     
            Private Sub GenerateEquals(ByVal tb As TypeBuilder, ByVal fields As FieldInfo())  
                Dim mb As MethodBuilder = tb.DefineMethod("Equals", MethodAttributes.[Public] Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig, GetType(Boolean), New Type() {GetType(Object)})  
                Dim gen As ILGenerator = mb.GetILGenerator()  
                Dim other As LocalBuilder = gen.DeclareLocal(tb)  
                Dim [next] As Label = gen.DefineLabel()  
                gen.Emit(OpCodes.Ldarg_1)  
                gen.Emit(OpCodes.Isinst, tb)  
                gen.Emit(OpCodes.Stloc, other)  
                gen.Emit(OpCodes.Ldloc, other)  
                gen.Emit(OpCodes.Brtrue_S, [next])  
                gen.Emit(OpCodes.Ldc_I4_0)  
                gen.Emit(OpCodes.Ret)  
                gen.MarkLabel([next])  
                For Each field As FieldInfo In fields  
                    Dim ft As Type = field.FieldType  
                    Dim ct As Type = GetType(EqualityComparer(Of )).MakeGenericType(ft)  
                    [next] = gen.DefineLabel()  
                    gen.EmitCall(OpCodes.[Call], ct.GetMethod("get_Default"), Nothing)  
                    gen.Emit(OpCodes.Ldarg_0)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.Emit(OpCodes.Ldloc, other)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", New Type() {ft, ft}), Nothing)  
                    gen.Emit(OpCodes.Brtrue_S, [next])  
                    gen.Emit(OpCodes.Ldc_I4_0)  
                    gen.Emit(OpCodes.Ret)  
                    gen.MarkLabel([next])  
                Next  
                gen.Emit(OpCodes.Ldc_I4_1)  
                gen.Emit(OpCodes.Ret)  
            End Sub  
     
            Private Sub GenerateGetHashCode(ByVal tb As TypeBuilder, ByVal fields As FieldInfo())  
                Dim mb As MethodBuilder = tb.DefineMethod("GetHashCode", MethodAttributes.[Public] Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig, GetType(Integer), Type.EmptyTypes)  
                Dim gen As ILGenerator = mb.GetILGenerator()  
                gen.Emit(OpCodes.Ldc_I4_0)  
                For Each field As FieldInfo In fields  
                    Dim ft As Type = field.FieldType  
                    Dim ct As Type = GetType(EqualityComparer(Of )).MakeGenericType(ft)  
                    gen.EmitCall(OpCodes.[Call], ct.GetMethod("get_Default"), Nothing)  
                    gen.Emit(OpCodes.Ldarg_0)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", New Type() {ft}), Nothing)  
                    gen.Emit(OpCodes.[Xor])  
                Next  
                gen.Emit(OpCodes.Ret)  
            End Sub  
        End Class  
     
        Public NotInheritable Class ParseException  
            Inherits Exception  
            Private m_position As Integer  
     
            Public Sub New(ByVal message As String, ByVal position As Integer)  
                MyBase.New(message)  
                Me.m_position = position  
            End Sub  
     
            Public ReadOnly Property Position() As Integer  
                Get  
                    Return m_position  
                End Get  
            End Property  
     
            Public Overrides Function ToString() As String  
                Return String.Format(Res.ParseExceptionFormat, Message, m_position)  
            End Function  
        End Class  
     
        Friend Class ExpressionParser  
            Private Structure myToken  
                Public id As TokenId  
                Public text As String  
                Public pos As Integer  
            End Structure  
     
            Private Enum TokenId  
                Unknown  
                [End]  
                Identifier  
                StringLiteral  
                IntegerLiteral  
                RealLiteral  
                Exclamation  
                Percent  
                Amphersand  
                OpenParen  
                CloseParen  
                Asterisk  
                Plus  
                Comma  
                Minus  
                Dot  
                Slash  
                Colon  
                LessThan  
                Equal  
                GreaterThan  
                Question  
                OpenBracket  
                CloseBracket  
                Bar  
                ExclamationEqual  
                DoubleAmphersand  
                LessThanEqual  
                LessGreater  
                DoubleEqual  
                GreaterThanEqual  
                DoubleBar  
            End Enum  
     
            Private Interface ILogicalSignatures  
                Sub F(ByVal x As Boolean, ByVal y As Boolean)  
                Sub F(ByVal x As Global.System.Nullable(Of Boolean), ByVal y As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IArithmeticSignatures  
                Sub F(ByVal x As Integer, ByVal y As Integer)  
                Sub F(ByVal x As UInteger, ByVal y As UInteger)  
                Sub F(ByVal x As Long, ByVal y As Long)  
                Sub F(ByVal x As ULong, ByVal y As ULong)  
                Sub F(ByVal x As Single, ByVal y As Single)  
                Sub F(ByVal x As Double, ByVal y As Double)  
                Sub F(ByVal x As Decimal, ByVal y As Decimal)  
                Sub F(ByVal x As Global.System.Nullable(Of Integer), ByVal y As Global.System.Nullable(Of Integer))  
                Sub F(ByVal x As Global.System.Nullable(Of UInteger), ByVal y As Global.System.Nullable(Of UInteger))  
                Sub F(ByVal x As Global.System.Nullable(Of Long), ByVal y As Global.System.Nullable(Of Long))  
                Sub F(ByVal x As Global.System.Nullable(Of ULong), ByVal y As Global.System.Nullable(Of ULong))  
                Sub F(ByVal x As Global.System.Nullable(Of Single), ByVal y As Global.System.Nullable(Of Single))  
                Sub F(ByVal x As Global.System.Nullable(Of Double), ByVal y As Global.System.Nullable(Of Double))  
                Sub F(ByVal x As Global.System.Nullable(Of Decimal), ByVal y As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Private Interface IRelationalSignatures  
                Inherits IArithmeticSignatures  
                Overloads Sub F(ByVal x As String, ByVal y As String)  
                Overloads Sub F(ByVal x As Char, ByVal y As Char)  
                Overloads Sub F(ByVal x As DateTime, ByVal y As DateTime)  
                Overloads Sub F(ByVal x As TimeSpan, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of Char), ByVal y As Global.System.Nullable(Of Char))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of DateTime))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of TimeSpan), ByVal y As Global.System.Nullable(Of TimeSpan))  
            End Interface  
     
            Private Interface IEqualitySignatures  
                Inherits IRelationalSignatures  
                Overloads Sub F(ByVal x As Boolean, ByVal y As Boolean)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of Boolean), ByVal y As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IAddSignatures  
                Inherits IArithmeticSignatures  
                Overloads Sub F(ByVal x As DateTime, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As TimeSpan, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of TimeSpan))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of TimeSpan), ByVal y As Global.System.Nullable(Of TimeSpan))  
            End Interface  
     
            Private Interface ISubtractSignatures  
                Inherits IAddSignatures  
                Overloads Sub F(ByVal x As DateTime, ByVal y As DateTime)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of DateTime))  
            End Interface  
     
            Private Interface INegationSignatures  
                Sub F(ByVal x As Integer)  
                Sub F(ByVal x As Long)  
                Sub F(ByVal x As Single)  
                Sub F(ByVal x As Double)  
                Sub F(ByVal x As Decimal)  
                Sub F(ByVal x As Global.System.Nullable(Of Integer))  
                Sub F(ByVal x As Global.System.Nullable(Of Long))  
                Sub F(ByVal x As Global.System.Nullable(Of Single))  
                Sub F(ByVal x As Global.System.Nullable(Of Double))  
                Sub F(ByVal x As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Private Interface INotSignatures  
                Sub F(ByVal x As Boolean)  
                Sub F(ByVal x As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IEnumerableSignatures  
                Sub Where(ByVal predicate As Boolean)  
                Sub Any()  
                Sub Any(ByVal predicate As Boolean)  
                Sub All(ByVal predicate As Boolean)  
                Sub Count()  
                Sub Count(ByVal predicate As Boolean)  
                Sub Min(ByVal selector As Object)  
                Sub Max(ByVal selector As Object)  
                Sub Sum(ByVal selector As Integer)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Integer))  
                Sub Sum(ByVal selector As Long)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Long))  
                Sub Sum(ByVal selector As Single)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Single))  
                Sub Sum(ByVal selector As Double)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Double))  
                Sub Sum(ByVal selector As Decimal)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Decimal))  
                Sub Average(ByVal selector As Integer)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Integer))  
                Sub Average(ByVal selector As Long)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Long))  
                Sub Average(ByVal selector As Single)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Single))  
                Sub Average(ByVal selector As Double)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Double))  
                Sub Average(ByVal selector As Decimal)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Shared ReadOnly predefinedTypes As Type() = {GetType([Object]), GetType([Boolean]), GetType([Char]), GetType([String]), GetType([SByte]), GetType([Byte]), _  
             GetType(Int16), GetType(UInt16), GetType(Int32), GetType(UInt32), GetType(Int64), GetType(UInt64), _  
             GetType([Single]), GetType([Double]), GetType([Decimal]), GetType(DateTime), GetType(TimeSpan), GetType(Guid), _  
             GetType(Math), GetType(Convert)}  
     
            Shared ReadOnly trueLiteral As ExpressionExpression = Expression.Constant(True)  
            Shared ReadOnly falseLiteral As ExpressionExpression = Expression.Constant(False)  
            Shared ReadOnly nullLiteral As ExpressionExpression = Expression.Constant(Nothing)  
     
            Shared ReadOnly keywordIt As String = "it" 
            Shared ReadOnly keywordIif As String = "iif" 
            Shared ReadOnly keywordNew As String = "new" 
     
            Shared keywords As Dictionary(Of String, Object)  
     
            Private symbols As Dictionary(Of String, Object)  
            Private externals As IDictionary(Of String, Object)  
            Private literals As Dictionary(Of Expression, String)  
            Private it As ParameterExpression  
            Private text As String  
            Private textPos As Integer  
            Private textLen As Integer  
            Private ch As Char  
            Private varToken As myToken  
     
            Public Sub New(ByVal parameters As ParameterExpression(), ByVal expression As String, ByVal values As Object())  
                If expression Is Nothing Then  
                    Throw New ArgumentNullException("expression")  
                End If  
                If keywords Is Nothing Then  
                    keywords = CreateKeywords()  
                End If  
                symbols = New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)  
                literals = New Dictionary(Of Expression, String)()  
                If parameters IsNot Nothing Then  
                    ProcessParameters(parameters)  
                End If  
                If values IsNot Nothing Then  
                    ProcessValues(values)  
                End If  
                text = expression 
                texttextLen = text.Length  
                SetTextPos(0)  
                NextToken()  
            End Sub  
     
            Private Sub ProcessParameters(ByVal parameters As ParameterExpression())  
                For Each pe As ParameterExpression In parameters  
                    If Not [String].IsNullOrEmpty(pe.Name) Then  
                        AddSymbol(pe.Name, pe)  
                    End If  
                Next  
                If parameters.Length = 1 AndAlso [String].IsNullOrEmpty(parameters(0).Name) Then  
                    it = parameters(0)  
                End If  
            End Sub  
     
            Private Sub ProcessValues(ByVal values As Object())  
                For i As Integer = 0 To values.Length - 1  
                    Dim value As Object = values(i)  
                    If i = values.Length - 1 AndAlso TypeOf value Is IDictionary(Of String, Object) Then  
                        externals = DirectCast(value, IDictionary(Of String, Object))  
                    Else  
                        AddSymbol("@" & i.ToString(Globalization.CultureInfo.InvariantCulture), value)  
                    End If  
                Next  
            End Sub  
     
            Private Sub AddSymbol(ByVal name As String, ByVal value As Object)  
                If symbols.ContainsKey(name) Then  
                    Throw ParseError(Res.DuplicateIdentifier, name)  
                End If  
                symbols.Add(name, value)  
            End Sub  
     
            Public Function Parse(ByVal resultType As Type) As Expression  
                Dim exprPos As Integer = varToken.pos  
                Dim expr As Expression = ParseExpression()  
                If resultType IsNot Nothing Then  
                    If (InlineAssignHelper(expr, PromoteExpression(expr, resultType, True))) Is Nothing Then  
                        Throw ParseError(exprPos, Res.ExpressionTypeMismatch, GetTypeName(resultType))  
                    End If  
                End If  
                ValidateToken(TokenId.[End], Res.SyntaxError)  
                Return expr  
            End Function  
     
            '#Pragma warning disable 0219  
            Public Function ParseOrdering() As IEnumerable(Of DynamicOrdering)  
                Dim orderings As New List(Of DynamicOrdering)()  
                While True  
                    Dim expr As Expression = ParseExpression()  
                    Dim ascending As Boolean = True 
                    If TokenIdentifierIs("asc") OrElse TokenIdentifierIs("ascending") Then  
                        NextToken()  
                    ElseIf TokenIdentifierIs("desc") OrElse TokenIdentifierIs("descending") Then  
                        NextToken()  
                        ascending = False 
                    End If  
                    orderings.Add(New DynamicOrdering() With { _  
                      .Selector = expr, _  
                      .Ascending = ascending _  
                    })  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                ValidateToken(TokenId.[End], Res.SyntaxError)  
                Return orderings  
            End Function  
            '#Pragma warning restore 0219  
     
            ' ?: operator  
            Private Function ParseExpression() As Expression  
                Dim errorPos As Integer = varToken.pos  
                Dim expr As Expression = ParseLogicalOr()  
                If varToken.id = TokenId.Question Then  
                    NextToken()  
                    Dim expr1 As Expression = ParseExpression()  
                    ValidateToken(TokenId.Colon, Res.ColonExpected)  
                    NextToken()  
                    Dim expr2 As Expression = ParseExpression()  
                    expr = GenerateConditional(expr, expr1, expr2, errorPos)  
                End If  
                Return expr  
            End Function  
     
            ' ||, or operator  
            Private Function ParseLogicalOr() As Expression  
                Dim left As Expression = ParseLogicalAnd()  
                While varToken.id = TokenId.DoubleBar OrElse TokenIdentifierIs("or")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseLogicalAnd()  
                    CheckAndPromoteOperands(GetType(ILogicalSignatures), op.text, left, right, op.pos)  
                    left = Expression.[OrElse](left, right)  
                End While  
                Return left  
            End Function  
     
            ' &&, and operator  
            Private Function ParseLogicalAnd() As Expression  
                Dim left As Expression = ParseComparison()  
                While varToken.id = TokenId.DoubleAmphersand OrElse TokenIdentifierIs("and")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseComparison()  
                    CheckAndPromoteOperands(GetType(ILogicalSignatures), op.text, left, right, op.pos)  
                    left = Expression.[AndAlso](left, right)  
                End While  
                Return left  
            End Function  
     
            ' =, ==, !=, <>, >>=, <<= operators  
            Private Function ParseComparison() As Expression  
                Dim left As Expression = ParseAdditive()  
                While varToken.id = TokenId.Equal OrElse varToken.id = TokenId.DoubleEqual OrElse varToken.id = TokenId.ExclamationEqual OrElse varToken.id = TokenId.LessGreater OrElse varToken.id = TokenId.GreaterThan OrElse varToken.id = TokenId.GreaterThanEqual OrElse varToken.id = TokenId.LessThan OrElse varToken.id = TokenId.LessThanEqual  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseAdditive()  
                    Dim isEquality As Boolean = op.id = TokenId.Equal OrElse op.id = TokenId.DoubleEqual OrElse op.id = TokenId.ExclamationEqual OrElse op.id = TokenId.LessGreater  
                    If isEquality AndAlso Not left.Type.IsValueType AndAlso Not right.Type.IsValueType Then  
                        If Not left.Type.Equals(right.Type) Then  
                            If left.Type.IsAssignableFrom(right.Type) Then  
                                right = Expression.Convert(right, left.Type)  
                            ElseIf right.Type.IsAssignableFrom(left.Type) Then  
                                left = Expression.Convert(left, right.Type)  
                            Else  
                                Throw IncompatibleOperandsError(op.text, left, right, op.pos)  
                            End If  
                        End If  
                    ElseIf IsEnumType(left.Type) OrElse IsEnumType(right.Type) Then  
                        If Not left.Type.Equals(right.Type) Then  
                            Dim e As Expression  
                            If (InlineAssignHelper(e, PromoteExpression(right, left.Type, True))) IsNot Nothing Then  
                                right = e 
                            ElseIf (InlineAssignHelper(e, PromoteExpression(left, right.Type, True))) IsNot Nothing Then  
                                left = e  
                            Else  
                                Throw IncompatibleOperandsError(op.text, left, right, op.pos)  
                            End If  
                        End If  
                    Else  
                        CheckAndPromoteOperands(If(isEquality, GetType(IEqualitySignatures), GetType(IRelationalSignatures)), op.text, left, right, op.pos)  
                    End If  
                    Select Case op.id  
                        Case TokenId.Equal, TokenId.DoubleEqual  
                            left = GenerateEqual(left, right)  
                            Exit Select  
                        Case TokenId.ExclamationEqual, TokenId.LessGreater  
                            left = GenerateNotEqual(left, right)  
                            Exit Select  
                        Case TokenId.GreaterThan  
                            left = GenerateGreaterThan(left, right)  
                            Exit Select  
                        Case TokenId.GreaterThanEqual  
                            left = GenerateGreaterThanEqual(left, right)  
                            Exit Select  
                        Case TokenId.LessThan  
                            left = GenerateLessThan(left, right)  
                            Exit Select  
                        Case TokenId.LessThanEqual  
                            left = GenerateLessThanEqual(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' +, -, & operators  
            Private Function ParseAdditive() As Expression  
                Dim left As Expression = ParseMultiplicative()  
                While varToken.id = TokenId.Plus OrElse varToken.id = TokenId.Minus OrElse varToken.id = TokenId.Amphersand  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseMultiplicative()  
                    Select Case op.id  
                        Case TokenId.Plus  
                            If left.Type.Equals(GetType(String)) OrElse right.Type.Equals(GetType(String)) Then  
                                left = GenerateStringConcat(left, right)  
                                Exit Select  
                            End If  
                            CheckAndPromoteOperands(GetType(IAddSignatures), op.text, left, right, op.pos)  
                            left = GenerateAdd(left, right)  
                            Exit Select  
                        Case TokenId.Minus  
                            CheckAndPromoteOperands(GetType(ISubtractSignatures), op.text, left, right, op.pos)  
                            left = GenerateSubtract(left, right)  
                            Exit Select  
                        Case TokenId.Amphersand  
                            left = GenerateStringConcat(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' *, /, %, mod operators  
            Private Function ParseMultiplicative() As Expression  
                Dim left As Expression = ParseUnary()  
                While varToken.id = TokenId.Asterisk OrElse varToken.id = TokenId.Slash OrElse varToken.id = TokenId.Percent OrElse TokenIdentifierIs("mod")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseUnary()  
                    CheckAndPromoteOperands(GetType(IArithmeticSignatures), op.text, left, right, op.pos)  
                    Select Case op.id  
                        Case TokenId.Asterisk  
                            left = Expression.Multiply(left, right)  
                            Exit Select  
                        Case TokenId.Slash  
                            left = Expression.Divide(left, right)  
                            Exit Select  
                        Case TokenId.Percent, TokenId.Identifier  
                            left = Expression.Modulo(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' -, !, not unary operators  
            Private Function ParseUnary() As Expression  
                If varToken.id = TokenId.Minus OrElse varToken.id = TokenId.Exclamation OrElse TokenIdentifierIs("not") Then  
                    Dim op As myToken = varToken 
                    NextToken()  
                    If op.id = TokenId.Minus AndAlso (varToken.id = TokenId.IntegerLiteral OrElse varToken.id = TokenId.RealLiteral) Then  
                        varToken.text = "-" & varToken.text  
                        varToken.pos = op.pos  
                        Return ParsePrimary()  
                    End If  
                    Dim expr As Expression = ParseUnary()  
                    If op.id = TokenId.Minus Then  
                        CheckAndPromoteOperand(GetType(INegationSignatures), op.text, expr, op.pos)  
                        expr = Expression.Negate(expr)  
                    Else  
                        CheckAndPromoteOperand(GetType(INotSignatures), op.text, expr, op.pos)  
                        expr = Expression.[Not](expr)  
                    End If  
                    Return expr  
                End If  
                Return ParsePrimary()  
            End Function  
     
            Private Function ParsePrimary() As Expression  
                Dim expr As Expression = ParsePrimaryStart()  
                While True  
                    If varToken.id = TokenId.Dot Then  
                        NextToken()  
                        expr = ParseMemberAccess(Nothing, expr)  
                    ElseIf varToken.id = TokenId.OpenBracket Then  
                        expr = ParseElementAccess(expr)  
                    Else  
                        Exit While  
                    End If  
                End While  
                Return expr  
            End Function  
     
            Private Function ParsePrimaryStart() As Expression  
                Select Case varToken.id  
                    Case TokenId.Identifier  
                        Return ParseIdentifier()  
                    Case TokenId.StringLiteral  
                        Return ParseStringLiteral()  
                    Case TokenId.IntegerLiteral  
                        Return ParseIntegerLiteral()  
                    Case TokenId.RealLiteral  
                        Return ParseRealLiteral()  
                    Case TokenId.OpenParen  
                        Return ParseParenExpression()  
                    Case Else  
                        Throw ParseError(Res.ExpressionExpected)  
                End Select  
            End Function  
     
            Private Function ParseStringLiteral() As Expression  
                ValidateToken(TokenId.StringLiteral)  
                Dim quote As Char = varToken.text(0)  
                Dim s As String = varToken.text.Substring(1, varToken.text.Length - 2)  
                Dim start As Integer = 0 
                While True  
                    Dim i As Integer = s.IndexOf(quote, start)  
                    If i < 0 Then  
                        Exit While  
                    End If  
                    ss = s.Remove(i, 1)  
                    start = i + 1  
                End While  
                If quote = "'"c Then  
                    If s.Length <> 1 Then  
                        Throw ParseError(Res.InvalidCharacterLiteral)  
                    End If  
                    NextToken()  
                    Return CreateLiteral(s(0), s)  
                End If  
                NextToken()  
                Return CreateLiteral(s, s)  
            End Function  
     
            Private Function ParseIntegerLiteral() As Expression  
                ValidateToken(TokenId.IntegerLiteral)  
                Dim text As String = varToken.text  
                If text(0) <> "-"c Then  
                    Dim value As ULong  
                    If Not UInt64.TryParse(text, value) Then  
                        Throw ParseError(Res.InvalidIntegerLiteral, text)  
                    End If  
                    NextToken()  
                    If value <= CULng(Int32.MaxValue) Then  
                        Return CreateLiteral(CInt(value), text)  
                    End If  
                    If value <= CULng(UInt32.MaxValue) Then  
                        Return CreateLiteral(CUInt(value), text)  
                    End If  
                    If value <= CULng(Int64.MaxValue) Then  
                        Return CreateLiteral(CLng(value), text)  
                    End If  
                    Return CreateLiteral(value, text)  
                Else  
                    Dim value As Long  
                    If Not Int64.TryParse(text, value) Then  
                        Throw ParseError(Res.InvalidIntegerLiteral, text)  
                    End If  
                    NextToken()  
                    If value >= Int32.MinValue AndAlso value <= Int32.MaxValue Then  
                        Return CreateLiteral(CInt(value), text)  
                    End If  
                    Return CreateLiteral(value, text)  
                End If  
            End Function  
     
            Private Function ParseRealLiteral() As Expression  
                ValidateToken(TokenId.RealLiteral)  
                Dim text As String = varToken.text  
                Dim value As Object = Nothing 
                Dim last As Char = text(text.Length - 1)  
                If last = "F"c OrElse last = "f"c Then  
                    Dim f As Single  
                    If [Single].TryParse(text.Substring(0, text.Length - 1), f) Then  
                        value = f 
                    End If  
                Else  
                    Dim d As Double  
                    If [Double].TryParse(text, d) Then  
                        value = d 
                    End If  
                End If  
                If value Is Nothing Then  
                    Throw ParseError(Res.InvalidRealLiteral, text)  
                End If  
                NextToken()  
                Return CreateLiteral(value, text)  
            End Function  
     
            Private Function CreateLiteral(ByVal value As Object, ByVal text As String) As Expression  
                Dim expr As ConstantExpression = Expression.Constant(value)  
                literals.Add(expr, text)  
                Return expr  
            End Function  
     
            Private Function ParseParenExpression() As Expression  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim e As Expression = ParseExpression()  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected)  
                NextToken()  
                Return e  
            End Function  
     
            Private Function ParseIdentifier() As Expression  
                ValidateToken(TokenId.Identifier)  
                Dim value As Object  
                If keywords.TryGetValue(varToken.text, value) Then  
                    If TypeOf value Is Type Then  
                        Return ParseTypeAccess(DirectCast(value, Type))  
                    End If  
                    If value Is DirectCast(keywordIt, Object) Then  
                        Return ParseIt()  
                    End If  
                    If value Is DirectCast(keywordIif, Object) Then  
                        Return ParseIif()  
                    End If  
                    If value Is DirectCast(keywordNew, Object) Then  
                        Return ParseNew()  
                    End If  
                    NextToken()  
                    Return DirectCast(value, Expression)  
                End If  
                If symbols.TryGetValue(varToken.text, value) OrElse externals IsNot Nothing AndAlso externals.TryGetValue(varToken.text, value) Then  
                    Dim expr As Expression = TryCast(value, Expression)  
                    If expr Is Nothing Then  
                        expr = Expression.Constant(value)  
                    Else  
                        Dim lambda As LambdaExpression = TryCast(expr, LambdaExpression)  
                        If lambda IsNot Nothing Then  
                            Return ParseLambdaInvocation(lambda)  
                        End If  
                    End If  
                    NextToken()  
                    Return expr  
                End If  
                If it IsNot Nothing Then  
                    Return ParseMemberAccess(Nothing, it)  
                End If  
                Throw ParseError(Res.UnknownIdentifier, varToken.text)  
            End Function  
     
            Private Function ParseIt() As Expression  
                If it Is Nothing Then  
                    Throw ParseError(Res.NoItInScope)  
                End If  
                NextToken()  
                Return it  
            End Function  
     
            Private Function ParseIif() As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                Dim args As Expression() = ParseArgumentList()  
                If args.Length <> 3 Then  
                    Throw ParseError(errorPos, Res.IifRequiresThreeArgs)  
                End If  
                Return GenerateConditional(args(0), args(1), args(2), errorPos)  
            End Function  
     
            Private Function GenerateConditional(ByVal test As Expression, ByVal expr1 As Expression, ByVal expr2 As Expression, ByVal errorPos As Integer) As Expression  
                If Not test.Type.Equals(GetType(Boolean)) Then  
                    Throw ParseError(errorPos, Res.FirstExprMustBeBool)  
                End If  
                If Not expr1.Type.Equals(expr2.Type) Then  
                    Dim expr1as2 As Expression = If(Not expr2.Equals(nullLiteral), PromoteExpression(expr1, expr2.Type, True), Nothing)  
                    Dim expr2as1 As Expression = If(Not expr2.Equals(nullLiteral), PromoteExpression(expr2, expr1.Type, True), Nothing)  
                    If expr1as2 IsNot Nothing AndAlso expr2as1 Is Nothing Then  
                        expr1 = expr1as2 
                    ElseIf expr2as1 IsNot Nothing AndAlso expr1as2 Is Nothing Then  
                        expr2 = expr2as1 
                    Else  
                        Dim type1 As String = If(Not expr2.Equals(nullLiteral), expr1.Type.Name, "null")  
                        Dim type2 As String = If(Not expr2.Equals(nullLiteral), expr2.Type.Name, "null")  
                        If expr1as2 IsNot Nothing AndAlso expr2as1 IsNot Nothing Then  
                            Throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2)  
                        End If  
                        Throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2)  
                    End If  
                End If  
                Return Expression.Condition(test, expr1, expr2)  
            End Function  
     
            Private Function ParseNew() As Expression  
                NextToken()  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim properties As New List(Of DynamicProperty)()  
                Dim expressions As New List(Of Expression)()  
                While True  
                    Dim exprPos As Integer = varToken.pos  
                    Dim expr As Expression = ParseExpression()  
                    Dim propName As String  
                    If TokenIdentifierIs("as") Then  
                        NextToken()  
                        propName = GetIdentifier()  
                        NextToken()  
                    Else  
                        Dim [me] As MemberExpression = TryCast(expr, MemberExpression)  
                        If [me] Is Nothing Then  
                            Throw ParseError(exprPos, Res.MissingAsClause)  
                        End If  
                        propName = [me].Member.Name  
                    End If  
                    expressions.Add(expr)  
                    properties.Add(New DynamicProperty(propName, expr.Type))  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)  
                NextToken()  
                Dim type As Type = DynamicExpression.CreateClass(properties)  
                Dim bindings As MemberBinding() = New MemberBinding(properties.Count - 1) {}  
                For i As Integer = 0 To bindings.Length - 1  
                    bindings(i) = Expression.Bind(type.GetProperty(properties(i).Name), expressions(i))  
                Next  
                Return Expression.MemberInit(Expression.[New](type), bindings)  
            End Function  
     
            Private Function ParseLambdaInvocation(ByVal lambda As LambdaExpression) As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                Dim args As Expression() = ParseArgumentList()  
                Dim method As MethodBase  
                If FindMethod(lambda.Type, "Invoke", False, args, method) <> 1 Then  
                    Throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda)  
                End If  
                Return Expression.Invoke(lambda, args)  
            End Function  
     
            Private Function ParseTypeAccess(ByVal type As Type) As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                If varToken.id = TokenId.Question Then  
                    If Not type.IsValueType OrElse IsNullableType(type) Then  
                        Throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type))  
                    End If  
                    type = GetType(Nullable(Of )).MakeGenericType(type)  
                    NextToken()  
                End If  
                If varToken.id = TokenId.OpenParen Then  
                    Dim args As Expression() = ParseArgumentList()  
                    Dim method As MethodBase  
                    Select Case FindBestMethod(type.GetConstructors(), args, method)  
                        Case 0  
                            If args.Length = 1 Then  
                                Return GenerateConversion(args(0), type, errorPos)  
                            End If  
                            Throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type))  
                        Case 1  
                            Return Expression.[New](DirectCast(method, ConstructorInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type))  
                    End Select  
                End If  
                ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected)  
                NextToken()  
                Return ParseMemberAccess(type, Nothing)  
            End Function  
     
            Private Function GenerateConversion(ByVal expr As Expression, ByVal type As Type, ByVal errorPos As Integer) As Expression  
                Dim exprType As Type = expr.Type  
                If exprType Is type Then  
                    Return expr  
                End If  
                If exprType.IsValueType AndAlso type.IsValueType Then  
                    If (IsNullableType(exprType) OrElse IsNullableType(type)) AndAlso GetNonNullableType(exprType) Is GetNonNullableType(type) Then  
                        Return Expression.Convert(expr, type)  
                    End If  
                    If (IsNumericType(exprType) OrElse IsEnumType(exprType)) AndAlso (IsNumericType(type)) OrElse IsEnumType(type) Then  
                        Return Expression.ConvertChecked(expr, type)  
                    End If  
                End If  
                If exprType.IsAssignableFrom(type) OrElse type.IsAssignableFrom(exprType) OrElse exprType.IsInterface OrElse type.IsInterface Then  
                    Return Expression.Convert(expr, type)  
                End If  
                Throw ParseError(errorPos, Res.CannotConvertValue, GetTypeName(exprType), GetTypeName(type))  
            End Function  
     
            Private Function ParseMemberAccess(ByVal type As Type, ByVal instance As Expression) As Expression  
                If instance IsNot Nothing Then  
                    type = instance.Type  
                End If  
                Dim errorPos As Integer = varToken.pos  
                Dim id As String = GetIdentifier()  
                NextToken()  
                If varToken.id = TokenId.OpenParen Then  
                    If instance IsNot Nothing AndAlso type IsNot GetType(String) Then  
                        Dim enumerableType As Type = FindGenericType(GetType(IEnumerable(Of )), type)  
                        If enumerableType IsNot Nothing Then  
                            Dim elementType As Type = enumerableType.GetGenericArguments()(0)  
                            Return ParseAggregate(instance, elementType, id, errorPos)  
                        End If  
                    End If  
                    Dim args As Expression() = ParseArgumentList()  
                    Dim mb As MethodBase  
                    Select Case FindMethod(type, id, instance Is Nothing, args, mb)  
                        Case 0  
                            Throw ParseError(errorPos, Res.NoApplicableMethod, id, GetTypeName(type))  
                        Case 1  
                            Dim method As MethodInfo = DirectCast(mb, MethodInfo)  
                            If Not IsPredefinedType(method.DeclaringType) Then  
                                Throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType))  
                            End If  
                            If method.ReturnType Is GetType(Void) Then  
                                Throw ParseError(errorPos, Res.MethodIsVoid, id, GetTypeName(method.DeclaringType))  
                            End If  
                            Return Expression.[Call](instance, DirectCast(method, MethodInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousMethodInvocation, id, GetTypeName(type))  
                    End Select  
                Else  
                    Dim member As MemberInfo = FindPropertyOrField(type, id, instance Is Nothing)  
                    If member Is Nothing Then  
                        Throw ParseError(errorPos, Res.UnknownPropertyOrField, id, GetTypeName(type))  
                    End If  
                    Return If(TypeOf member Is PropertyInfo, Expression.[Property](instance, DirectCast(member, PropertyInfo)), Expression.Field(instance, DirectCast(member, FieldInfo)))  
                End If  
            End Function  
     
            Private Shared Function FindGenericType(ByVal generic As Type, ByVal type As Type) As Type  
                While type IsNot Nothing AndAlso type IsNot GetType(Object)  
                    If type.IsGenericType AndAlso type.GetGenericTypeDefinition() Is generic Then  
                        Return type  
                    End If  
                    If generic.IsInterface Then  
                        For Each intfType As Type In type.GetInterfaces()  
                            Dim found As Type = FindGenericType(generic, intfType)  
                            If found IsNot Nothing Then  
                                Return found  
                            End If  
                        Next  
                    End If  
                    typetype = type.BaseType  
                End While  
                Return Nothing  
            End Function  
     
            Private Function ParseAggregate(ByVal instance As Expression, ByVal elementType As Type, ByVal methodName As String, ByVal errorPos As Integer) As Expression  
                Dim outerIt As ParameterExpression = it 
                Dim innerIt As ParameterExpression = Expression.Parameter(elementType, "")  
                it = innerIt 
                Dim args As Expression() = ParseArgumentList()  
                it = outerIt 
                Dim signature As MethodBase  
                If FindMethod(GetType(IEnumerableSignatures), methodName, False, args, signature) <> 1 Then  
                    Throw ParseError(errorPos, Res.NoApplicableAggregate, methodName)  
                End If  
                Dim typeArgs As Type()  
                If signature.Name = "Min" OrElse signature.Name = "Max" Then  
                    typeArgs = New Type() {elementType, args(0).Type}  
                Else  
                    typeArgs = New Type() {elementType}  
                End If  
                If args.Length = 0 Then  
                    args = New Expression() {instance}  
                Else  
                    args = New Expression() {instance, Expression.Lambda(args(0), innerIt)}  
                End If  
                Return Expression.[Call](GetType(Enumerable), signature.Name, typeArgs, args)  
            End Function  
     
            Private Function ParseArgumentList() As Expression()  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim args As Expression() = If(varToken.id <> TokenId.CloseParen, ParseArguments(), New Expression(-1) {})  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)  
                NextToken()  
                Return args  
            End Function  
     
            Private Function ParseArguments() As Expression()  
                Dim argList As New List(Of Expression)()  
                While True  
                    argList.Add(ParseExpression())  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                Return argList.ToArray()  
            End Function  
     
            Private Function ParseElementAccess(ByVal expr As Expression) As Expression  
                Dim errorPos As Integer = varToken.pos  
                ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected)  
                NextToken()  
                Dim args As Expression() = ParseArguments()  
                ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected)  
                NextToken()  
                If expr.Type.IsArray Then  
                    If expr.Type.GetArrayRank() <> 1 OrElse args.Length <> 1 Then  
                        Throw ParseError(errorPos, Res.CannotIndexMultiDimArray)  
                    End If  
                    Dim index As Expression = PromoteExpression(args(0), GetType(Integer), True)  
                    If index Is Nothing Then  
                        Throw ParseError(errorPos, Res.InvalidIndex)  
                    End If  
                    Return Expression.ArrayIndex(expr, index)  
                Else  
                    Dim mb As MethodBase  
                    Select Case FindIndexer(expr.Type, args, mb)  
                        Case 0  
                            Throw ParseError(errorPos, Res.NoApplicableIndexer, GetTypeName(expr.Type))  
                        Case 1  
                            Return Expression.[Call](expr, DirectCast(mb, MethodInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousIndexerInvocation, GetTypeName(expr.Type))  
                    End Select  
                End If  
            End Function  
     
            Private Shared Function IsPredefinedType(ByVal type As Type) As Boolean  
                For Each t As Type In predefinedTypes  
                    If t Is type Then  
                        Return True  
                    End If  
                Next  
                Return False  
            End Function  
     
            Private Shared Function IsNullableType(ByVal type As Type) As Boolean  
                Return type.IsGenericType AndAlso type.GetGenericTypeDefinition() Is GetType(Nullable(Of ))  
            End Function  
     
            Private Shared Function GetNonNullableType(ByVal type As Type) As Type  
                Return If(IsNullableType(type), type.GetGenericArguments()(0), type)  
            End Function  
     
            Private Shared Function GetTypeName(ByVal type As Type) As String  
                Dim baseType As Type = GetNonNullableType(type)  
                Dim s As String = baseType.Name  
                If type IsNot baseType Then  
                    s += "?"c  
                End If  
                Return s  
            End Function  
     
            Private Shared Function IsNumericType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) <> 0  
            End Function  
     
            Private Shared Function IsSignedIntegralType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) = 2  
            End Function  
     
            Private Shared Function IsUnsignedIntegralType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) = 3  
            End Function  
     
            Private Shared Function GetNumericTypeKind(ByVal type__1 As Type) As Integer  
                type__1 = GetNonNullableType(type__1)  
                If type__1.IsEnum Then  
                    Return 0  
                End If  
                Select Case Type.GetTypeCode(type__1)  
                    Case TypeCode.[Char], TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                        Return 1  
                    Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64  
                        Return 2  
                    Case TypeCode.[Byte], TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64  
                        Return 3  
                    Case Else  
                        Return 0  
                End Select  
            End Function  
     
            Private Shared Function IsEnumType(ByVal type As Type) As Boolean  
                Return GetNonNullableType(type).IsEnum  
            End Function  
     
            Private Sub CheckAndPromoteOperand(ByVal signatures As Type, ByVal opName As String, ByRef expr As Expression, ByVal errorPos As Integer)  
                Dim args As Expression() = New Expression() {expr}  
                Dim method As MethodBase  
                If FindMethod(signatures, "F", False, args, method) <> 1 Then  
                    Throw ParseError(errorPos, Res.IncompatibleOperand, opName, GetTypeName(args(0).Type))  
                End If  
                expr = args(0)  
            End Sub  
     
            Private Sub CheckAndPromoteOperands(ByVal signatures As Type, ByVal opName As String, ByRef left As Expression, ByRef right As Expression, ByVal errorPos As Integer)  
                Dim args As Expression() = New Expression() {left, right}  
                Dim method As MethodBase  
                If FindMethod(signatures, "F", False, args, method) <> 1 Then  
                    Throw IncompatibleOperandsError(opName, left, right, errorPos)  
                End If  
                left = args(0)  
                right = args(1)  
            End Sub  
     
            Private Function IncompatibleOperandsError(ByVal opName As String, ByVal left As Expression, ByVal right As Expression, ByVal pos As Integer) As Exception  
                Return ParseError(pos, Res.IncompatibleOperands, opName, GetTypeName(left.Type), GetTypeName(right.Type))  
            End Function  
     
            Private Function FindPropertyOrField(ByVal type__1 As Type, ByVal memberName As String, ByVal staticAccess As Boolean) As MemberInfo  
                Dim flags As BindingFlagsBindingFlags = BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or (If(staticAccess, BindingFlags.[Static], BindingFlags.Instance))  
                For Each t As Type In SelfAndBaseTypes(type__1)  
                    Dim members As MemberInfo() = t.FindMembers(MemberTypes.[Property] Or MemberTypes.Field, flags, Type.FilterNameIgnoreCase, memberName)  
                    If members.Length <> 0 Then  
                        Return members(0)  
                    End If  
                Next  
                Return Nothing  
            End Function  
     
            Private Function FindMethod(ByVal type__1 As Type, ByVal methodName As String, ByVal staticAccess As Boolean, ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                Dim flags As BindingFlagsBindingFlags = BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or (If(staticAccess, BindingFlags.[Static], BindingFlags.Instance))  
                For Each t As Type In SelfAndBaseTypes(type__1)  
                    Dim members As MemberInfo() = t.FindMembers(MemberTypes.Method, flags, Type.FilterNameIgnoreCase, methodName)  
                    Dim count As Integer = FindBestMethod(members.Cast(Of MethodBase)(), args, method)  
                    If count <> 0 Then  
                        Return count  
                    End If  
                Next  
                method = Nothing 
                Return 0  
            End Function  
     
            Private Function FindIndexer(ByVal type As Type, ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                For Each t As Type In SelfAndBaseTypes(type)  
                    Dim members As MemberInfo() = t.GetDefaultMembers()  
                    If members.Length <> 0 Then  
                        Dim methods As IEnumerable(Of MethodBase) = members.OfType(Of PropertyInfo)().[Select](Function(p) DirectCast(p.GetGetMethod(), MethodBase)).Where(Function(m) m IsNot Nothing)  
                        Dim count As Integer = FindBestMethod(methods, args, method)  
                        If count <> 0 Then  
                            Return count  
                        End If  
                    End If  
                Next  
                method = Nothing 
                Return 0  
            End Function  
     
            Private Shared Function SelfAndBaseTypes(ByVal type As Type) As IEnumerable(Of Type)  
                If type.IsInterface Then  
                    Dim types As New List(Of Type)()  
                    AddInterface(types, type)  
                    Return types  
                End If  
                Return SelfAndBaseClasses(type)  
            End Function  
     
            Private Shared Function SelfAndBaseClasses(ByVal type As Type) As IEnumerable(Of Type)  
                While type IsNot Nothing  
                    Return New Type() {type}  
                    typetype = type.BaseType  
                End While  
            End Function  
     
            Private Shared Sub AddInterface(ByVal types As List(Of Type), ByVal type As Type)  
                If Not types.Contains(type) Then  
                    types.Add(type)  
                    For Each t As Type In type.GetInterfaces()  
                        AddInterface(types, t)  
                    Next  
                End If  
            End Sub  
     
            Private Class MethodData  
                Public MethodBase As MethodBase  
                Public Parameters As ParameterInfo()  
                Public Args As Expression()  
            End Class  
     
            Private Function FindBestMethod(ByVal methods As IEnumerable(Of MethodBase), ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                Dim applicable As MethodData() = methods.[Select](Function(m) New MethodData() With { _  
                  .MethodBase = m, _  
                  .Parameters = m.GetParameters() _  
                }).Where(Function(m) IsApplicable(m, args)).ToArray()  
                If applicable.Length > 1 Then  
                    applicableapplicable = applicable.Where(Function(m) applicable.All(Function(n) m.Equals(n) OrElse IsBetterThan(args, m, n))).ToArray()  
                End If  
                If applicable.Length = 1 Then  
                    Dim md As MethodData = applicable(0)  
                    For i As Integer = 0 To args.Length - 1  
                        args(i) = md.Args(i)  
                    Next  
                    method = md.MethodBase  
                Else  
                    method = Nothing 
                End If  
                Return applicable.Length  
            End Function  
     
            Private Function IsApplicable(ByVal method As MethodData, ByVal args As Expression()) As Boolean  
                If method.Parameters.Length <> args.Length Then  
                    Return False  
                End If  
                Dim promotedArgs As Expression() = New Expression(args.Length - 1) {}  
                For i As Integer = 0 To args.Length - 1  
                    Dim pi As ParameterInfo = method.Parameters(i)  
                    If pi.IsOut Then  
                        Return False  
                    End If  
                    Dim promoted As Expression = PromoteExpression(args(i), pi.ParameterType, False)  
                    If promoted Is Nothing Then  
                        Return False  
                    End If  
                    promotedArgs(i) = promoted  
                Next  
                method.Args = promotedArgs 
                Return True  
            End Function  
     
            Private Function PromoteExpression(ByVal expr As Expression, ByVal type__1 As Type, ByVal exact As Boolean) As Expression  
                If expr.Type.Equals(type__1) Then  
                    Return expr  
                End If  
                If TypeOf expr Is ConstantExpression Then  
                    Dim ce As ConstantExpression = DirectCast(expr, ConstantExpression)  
                    If ce.Equals(nullLiteral) Then  
                        If Not type__1.IsValueType OrElse IsNullableType(type__1) Then  
                            Return Expression.Constant(Nothing, type__1)  
                        End If  
                    Else  
                        Dim text As String  
                        If literals.TryGetValue(ce, text) Then  
                            Dim target As Type = GetNonNullableType(type__1)  
                            Dim value As [Object] = Nothing  
                            Select Case Type.GetTypeCode(ce.Type)  
                                Case TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64  
                                    value = ParseNumber(text, target)  
                                    Exit Select  
                                Case TypeCode.[Double]  
                                    If target Is GetType(Decimal) Then  
                                        value = ParseNumber(text, target)  
                                    End If  
                                    Exit Select  
                                Case TypeCode.[String]  
                                    value = ParseEnum(text, target)  
                                    Exit Select  
                            End Select  
                            If value IsNot Nothing Then  
                                Return Expression.Constant(value, type__1)  
                            End If  
                        End If  
                    End If  
                End If  
                If IsCompatibleWith(expr.Type, type__1) Then  
                    If type__1.IsValueType OrElse exact Then  
                        Return Expression.Convert(expr, type__1)  
                    End If  
                    Return expr  
                End If  
                Return Nothing  
            End Function  
     
            Private Shared Function ParseNumber(ByVal text As String, ByVal type__1 As Type) As Object  
                Select Case Type.GetTypeCode(GetNonNullableType(type__1))  
                    Case TypeCode.[SByte]  
                        Dim sb As SByte  
                        If SByte.TryParse(text, sb) Then  
                            Return sb  
                        End If  
                        Exit Select  
                    Case TypeCode.[Byte]  
                        Dim b As Byte  
                        If Byte.TryParse(text, b) Then  
                            Return b  
                        End If  
                        Exit Select  
                    Case TypeCode.Int16  
                        Dim s As Short  
                        If Short.TryParse(text, s) Then  
                            Return s  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt16  
                        Dim us As UShort  
                        If UShort.TryParse(text, us) Then  
                            Return us  
                        End If  
                        Exit Select  
                    Case TypeCode.Int32  
                        Dim i As Integer  
                        If Integer.TryParse(text, i) Then  
                            Return i  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt32  
                        Dim ui As UInteger  
                        If UInteger.TryParse(text, ui) Then  
                            Return ui  
                        End If  
                        Exit Select  
                    Case TypeCode.Int64  
                        Dim l As Long  
                        If Long.TryParse(text, l) Then  
                            Return l  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt64  
                        Dim ul As ULong  
                        If ULong.TryParse(text, ul) Then  
                            Return ul  
                        End If  
                        Exit Select  
                    Case TypeCode.[Single]  
                        Dim f As Single  
                        If Single.TryParse(text, f) Then  
                            Return f  
                        End If  
                        Exit Select  
                    Case TypeCode.[Double]  
                        Dim d As Double  
                        If Double.TryParse(text, d) Then  
                            Return d  
                        End If  
                        Exit Select  
                    Case TypeCode.[Decimal]  
                        Dim e As Decimal  
                        If Decimal.TryParse(text, e) Then  
                            Return e  
                        End If  
                        Exit Select  
                End Select  
                Return Nothing  
            End Function  
     
            Private Shared Function ParseEnum(ByVal name As String, ByVal type__1 As Type) As Object  
                If type__1.IsEnum Then  
                    Dim memberInfos As MemberInfo() = type__1.FindMembers(MemberTypes.Field, BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or BindingFlags.[Static], Type.FilterNameIgnoreCase, name)  
                    If memberInfos.Length <> 0 Then  
                        Return DirectCast(memberInfos(0), FieldInfo).GetValue(Nothing)  
                    End If  
                End If  
                Return Nothing  
            End Function  
     
            Private Shared Function IsCompatibleWith(ByVal source As Type, ByVal target As Type) As Boolean  
                If source Is target Then  
                    Return True  
                End If  
                If Not target.IsValueType Then  
                    Return target.IsAssignableFrom(source)  
                End If  
                Dim st As Type = GetNonNullableType(source)  
                Dim tt As Type = GetNonNullableType(target)  
                If st IsNot source AndAlso tt Is target Then  
                    Return False  
                End If  
                Dim sc As TypeCode = If(st.IsEnum, TypeCode.[Object], Type.GetTypeCode(st))  
                Dim tc As TypeCode = If(tt.IsEnum, TypeCode.[Object], Type.GetTypeCode(tt))  
                Select Case sc  
                    Case TypeCode.[SByte]  
                        Select Case tc  
                            Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], _  
                             TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.[Byte]  
                        Select Case tc  
                            Case TypeCode.[Byte], TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, _  
                             TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int16  
                        Select Case tc  
                            Case TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt16  
                        Select Case tc  
                            Case TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.[Single], _  
                             TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int32  
                        Select Case tc  
                            Case TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt32  
                        Select Case tc  
                            Case TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int64  
                        Select Case tc  
                            Case TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt64  
                        Select Case tc  
                            Case TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.[Single]  
                        Select Case tc  
                            Case TypeCode.[Single], TypeCode.[Double]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case Else  
                        If st Is tt Then  
                            Return True  
                        End If  
                        Exit Select  
                End Select  
                Return False  
            End Function  
     
            Private Shared Function IsBetterThan(ByVal args As Expression(), ByVal m1 As MethodData, ByVal m2 As MethodData) As Boolean  
                Dim better As Boolean = False 
                For i As Integer = 0 To args.Length - 1  
                    Dim c As Integer = CompareConversions(args(i).Type, m1.Parameters(i).ParameterType, m2.Parameters(i).ParameterType)  
                    If c < 0 Then  
                        Return False  
                    End If  
                    If c > 0 Then  
                        better = True 
                    End If  
                Next  
                Return better  
            End Function  
     
            ' Return 1 if s -> t1 is a better conversion than s -> t2  
            ' Return -1 if s -> t2 is a better conversion than s -> t1  
            ' Return 0 if neither conversion is better  
            Private Shared Function CompareConversions(ByVal s As Type, ByVal t1 As Type, ByVal t2 As Type) As Integer  
                If t1 Is t2 Then  
                    Return 0  
                End If  
                If s Is t1 Then  
                    Return 1  
                End If  
                If s Is t2 Then  
                    Return -1  
                End If  
                Dim t1t2 As Boolean = IsCompatibleWith(t1, t2)  
                Dim t2t1 As Boolean = IsCompatibleWith(t2, t1)  
                If t1t2 AndAlso Not t2t1 Then  
                    Return 1  
                End If  
                If t2t1 AndAlso Not t1t2 Then  
                    Return -1  
                End If  
                If IsSignedIntegralType(t1) AndAlso IsUnsignedIntegralType(t2) Then  
                    Return 1  
                End If  
                If IsSignedIntegralType(t2) AndAlso IsUnsignedIntegralType(t1) Then  
                    Return -1  
                End If  
                Return 0  
            End Function  
     
            Private Function GenerateEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.Equal(left, right)  
            End Function  
     
            Private Function GenerateNotEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.NotEqual(left, right)  
            End Function  
     
            Private Function GenerateGreaterThan(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.GreaterThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.GreaterThan(left, right)  
            End Function  
     
            Private Function GenerateGreaterThanEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.GreaterThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.GreaterThanOrEqual(left, right)  
            End Function  
     
            Private Function GenerateLessThan(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.LessThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.LessThan(left, right)  
            End Function  
     
            Private Function GenerateLessThanEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.LessThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.LessThanOrEqual(left, right)  
            End Function  
     
            Private Function GenerateAdd(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) AndAlso right.Type.Equals(GetType(String)) Then  
                    Return GenerateStaticMethodCall("Concat", left, right)  
                End If  
                Return Expression.Add(left, right)  
            End Function  
     
            Private Function GenerateSubtract(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.Subtract(left, right)  
            End Function  
     
            Private Function GenerateStringConcat(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.[Call](Nothing, GetType(String).GetMethod("Concat", New Object() {GetType(Object), GetType(Object)}), New Object() {left, right})  
            End Function  
     
            Private Function GetStaticMethod(ByVal methodName As String, ByVal left As Expression, ByVal right As Expression) As MethodInfo  
                Return left.Type.GetMethod(methodName, New Object() {left.Type, right.Type})  
            End Function  
     
            Private Function GenerateStaticMethodCall(ByVal methodName As String, ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.[Call](Nothing, GetStaticMethod(methodName, left, right), New Object() {left, right})  
            End Function  
     
            Private Sub SetTextPos(ByVal pos As Integer)  
                textPos = pos 
                ch = If(textPos < textLen, text(textPos), ControlChars.NullChar)  
            End Sub  
     
            Private Sub NextChar()  
                If textPos < textLen Then  
                    textPos += 1  
                End If  
                ch = If(textPos < textLen, text(textPos), ControlChars.NullChar)  
            End Sub  
     
            Private Sub NextToken()  
                While [Char].IsWhiteSpace(ch)  
                    NextChar()  
                End While  
                Dim t As TokenId  
                Dim tokenPos As Integer = textPos 
                Select Case ch  
                    Case "!"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.ExclamationEqual  
                        Else  
                            t = TokenId.Exclamation  
                        End If  
                        Exit Select  
                    Case "%"c  
                        NextChar()  
                        t = TokenId.Percent  
                        Exit Select  
                    Case "&"c  
                        NextChar()  
                        If cch = "&"c Then  
                            NextChar()  
                            t = TokenId.DoubleAmphersand  
                        Else  
                            t = TokenId.Amphersand  
                        End If  
                        Exit Select  
                    Case "("c  
                        NextChar()  
                        t = TokenId.OpenParen  
                        Exit Select  
                    Case ")"c  
                        NextChar()  
                        t = TokenId.CloseParen  
                        Exit Select  
                    Case "*"c  
                        NextChar()  
                        t = TokenId.Asterisk  
                        Exit Select  
                    Case "+"c  
                        NextChar()  
                        t = TokenId.Plus  
                        Exit Select  
                    Case ","c  
                        NextChar()  
                        t = TokenId.Comma  
                        Exit Select  
                    Case "-"c  
                        NextChar()  
                        t = TokenId.Minus  
                        Exit Select  
                    Case "."c  
                        NextChar()  
                        t = TokenId.Dot  
                        Exit Select  
                    Case "/"c  
                        NextChar()  
                        t = TokenId.Slash  
                        Exit Select  
                    Case ":"c  
                        NextChar()  
                        t = TokenId.Colon  
                        Exit Select  
                    Case "<"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.LessThanEqual  
                        ElseIf cch = ">"c Then  
                            NextChar()  
                            t = TokenId.LessGreater  
                        Else  
                            t = TokenId.LessThan  
                        End If  
                        Exit Select  
                    Case "="c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.DoubleEqual  
                        Else  
                            t = TokenId.Equal  
                        End If  
                        Exit Select  
                    Case ">"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.GreaterThanEqual  
                        Else  
                            t = TokenId.GreaterThan  
                        End If  
                        Exit Select  
                    Case "?"c  
                        NextChar()  
                        t = TokenId.Question  
                        Exit Select  
                    Case "["c  
                        NextChar()  
                        t = TokenId.OpenBracket  
                        Exit Select  
                    Case "]"c  
                        NextChar()  
                        t = TokenId.CloseBracket  
                        Exit Select  
                    Case "|"c  
                        NextChar()  
                        If cch = "|"c Then  
                            NextChar()  
                            t = TokenId.DoubleBar  
                        Else  
                            t = TokenId.Bar  
                        End If  
                        Exit Select  
                    Case """"c, "'"c  
                        Dim quote As Char = ch 
                        Do  
                            NextChar()  
                            While textPos < textLen AndAlso ch <> quote  
                                NextChar()  
                            End While  
                            If textPos = textLen Then  
                                Throw ParseError(textPos, Res.UnterminatedStringLiteral)  
                            End If  
                            NextChar()  
                        Loop While ch = quote 
                        t = TokenId.StringLiteral  
                        Exit Select  
                    Case Else  
                        If [Char].IsLetter(ch) OrElse cch = "@"c OrElse cch = "_"c Then  
                            Do  
                                NextChar()  
                            Loop While [Char].IsLetterOrDigit(ch) OrElse cch = "_"c  
                            t = TokenId.Identifier  
                            Exit Select  
                        End If  
                        If [Char].IsDigit(ch) Then  
                            t = TokenId.IntegerLiteral  
                            Do  
                                NextChar()  
                            Loop While [Char].IsDigit(ch)  
                            If cch = "."c Then  
                                t = TokenId.RealLiteral  
                                NextChar()  
                                ValidateDigit()  
                                Do  
                                    NextChar()  
                                Loop While [Char].IsDigit(ch)  
                            End If  
                            If cch = "E"c OrElse cch = "e"c Then  
                                t = TokenId.RealLiteral  
                                NextChar()  
                                If cch = "+"c OrElse cch = "-"c Then  
                                    NextChar()  
                                End If  
                                ValidateDigit()  
                                Do  
                                    NextChar()  
                                Loop While [Char].IsDigit(ch)  
                            End If  
                            If cch = "F"c OrElse cch = "f"c Then  
                                NextChar()  
                            End If  
                            Exit Select  
                        End If  
                        If textPos = textLen Then  
                            t = TokenId.[End]  
                            Exit Select  
                        End If  
                        Throw ParseError(textPos, Res.InvalidCharacter, ch)  
                End Select  
                varToken.id = t 
                varToken.text = text.Substring(tokenPos, textPos - tokenPos)  
                varToken.pos = tokenPos 
            End Sub  
     
            Private Function TokenIdentifierIs(ByVal id As String) As Boolean  
                Return varToken.id = TokenId.Identifier AndAlso [String].Equals(id, varToken.text, StringComparison.OrdinalIgnoreCase)  
            End Function  
     
            Private Function GetIdentifier() As String  
                ValidateToken(TokenId.Identifier, Res.IdentifierExpected)  
                Dim id As String = varToken.text  
                If id.Length > 1 AndAlso id(0) = "@"c Then  
                    idid = id.Substring(1)  
                End If  
                Return id  
            End Function  
     
            Private Sub ValidateDigit()  
                If Not [Char].IsDigit(ch) Then  
                    Throw ParseError(textPos, Res.DigitExpected)  
                End If  
            End Sub  
     
            Private Sub ValidateToken(ByVal t As TokenId, ByVal errorMessage As String)  
                If varToken.id <> t Then  
                    Throw ParseError(errorMessage)  
                End If  
            End Sub  
     
            Private Sub ValidateToken(ByVal t As TokenId)  
                If varToken.id <> t Then  
                    Throw ParseError(Res.SyntaxError)  
                End If  
            End Sub  
     
            Private Function ParseError(ByVal format As String, ByVal ParamArray args As Object()) As Exception  
                Return ParseError(varToken.pos, format, args)  
            End Function  
     
            Private Function ParseError(ByVal pos As Integer, ByVal format As String, ByVal ParamArray args As Object()) As Exception  
                Return New ParseException(String.Format(Globalization.CultureInfo.CurrentCulture, format, args), pos)  
            End Function  
     
            Private Shared Function CreateKeywords() As Dictionary(Of String, Object)  
                Dim d As New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)  
                d.Add("true", trueLiteral)  
                d.Add("false", falseLiteral)  
                d.Add("null", nullLiteral)  
                d.Add(keywordIt, keywordIt)  
                d.Add(keywordIif, keywordIif)  
                d.Add(keywordNew, keywordNew)  
                For Each type As Type In predefinedTypes  
                    d.Add(type.Name, type)  
                Next  
                Return d  
            End Function  
            Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T  
                target = value 
                Return value  
            End Function  
        End Class  
     
        NotInheritable Class Res  
            Private Sub New()  
            End Sub  
            Public Const DuplicateIdentifier As String = "The identifier '{0}' was defined more than once" 
            Public Const ExpressionTypeMismatch As String = "Expression of type '{0}' expected" 
            Public Const ExpressionExpected As String = "Expression expected" 
            Public Const InvalidCharacterLiteral As String = "Character literal must contain exactly one character" 
            Public Const InvalidIntegerLiteral As String = "Invalid integer literal '{0}'" 
            Public Const InvalidRealLiteral As String = "Invalid real literal '{0}'" 
            Public Const UnknownIdentifier As String = "Unknown identifier '{0}'" 
            Public Const NoItInScope As String = "No 'it' is in scope" 
            Public Const IifRequiresThreeArgs As String = "The 'iif' function requires three arguments" 
            Public Const FirstExprMustBeBool As String = "The first expression must be of type 'Boolean'" 
            Public Const BothTypesConvertToOther As String = "Both of the types '{0}' and '{1}' convert to the other" 
            Public Const NeitherTypeConvertsToOther As String = "Neither of the types '{0}' and '{1}' converts to the other" 
            Public Const MissingAsClause As String = "Expression is missing an 'as' clause" 
            Public Const ArgsIncompatibleWithLambda As String = "Argument list incompatible with lambda expression" 
            Public Const TypeHasNoNullableForm As String = "Type '{0}' has no nullable form" 
            Public Const NoMatchingConstructor As String = "No matching constructor in type '{0}'" 
            Public Const AmbiguousConstructorInvocation As String = "Ambiguous invocation of '{0}' constructor" 
            Public Const CannotConvertValue As String = "A value of type '{0}' cannot be converted to type '{1}'" 
            Public Const NoApplicableMethod As String = "No applicable method '{0}' exists in type '{1}'" 
            Public Const MethodsAreInaccessible As String = "Methods on type '{0}' are not accessible" 
            Public Const MethodIsVoid As String = "Method '{0}' in type '{1}' does not return a value" 
            Public Const AmbiguousMethodInvocation As String = "Ambiguous invocation of method '{0}' in type '{1}'" 
            Public Const UnknownPropertyOrField As String = "No property or field '{0}' exists in type '{1}'" 
            Public Const NoApplicableAggregate As String = "No applicable aggregate method '{0}' exists" 
            Public Const CannotIndexMultiDimArray As String = "Indexing of multi-dimensional arrays is not supported" 
            Public Const InvalidIndex As String = "Array index must be an integer expression" 
            Public Const NoApplicableIndexer As String = "No applicable indexer exists in type '{0}'" 
            Public Const AmbiguousIndexerInvocation As String = "Ambiguous invocation of indexer in type '{0}'" 
            Public Const IncompatibleOperand As String = "Operator '{0}' incompatible with operand type '{1}'" 
            Public Const IncompatibleOperands As String = "Operator '{0}' incompatible with operand types '{1}' and '{2}'" 
            Public Const UnterminatedStringLiteral As String = "Unterminated string literal" 
            Public Const InvalidCharacter As String = "Syntax error '{0}'" 
            Public Const DigitExpected As String = "Digit expected" 
            Public Const SyntaxError As String = "Syntax error" 
            Public Const TokenExpected As String = "{0} expected" 
            Public Const ParseExceptionFormat As String = "{0} (at index {1})" 
            Public Const ColonExpected As String = "':' expected" 
            Public Const OpenParenExpected As String = "'(' expected" 
            Public Const CloseParenOrOperatorExpected As String = "')' or operator expected" 
            Public Const CloseParenOrCommaExpected As String = "')' or ',' expected" 
            Public Const DotOrOpenParenExpected As String = "'.' or '(' expected" 
            Public Const OpenBracketExpected As String = "'[' expected" 
            Public Const CloseBracketOrCommaExpected As String = "']' or ',' expected" 
            Public Const IdentifierExpected As String = "Identifier expected" 
        End Class  
    End Namespace 
    I have finally converted the DataTable.cs and Dynamic.cs classes from Vlad's serialization example.  I will embed them here for anyone that is interested:
    DataTable.vb
    Imports System  
    Imports System.Collections.Generic  
    Imports System.Linq  
    Imports System.Collections  
    Imports System.Dynamic  
    Imports slSQLQueryWizard.SQLWiz.Dynamic  
    Namespace SQLWiz.Data  
        Public Class DataTable  
            Implements IEnumerable  
            Public Sub New(ByVal source As IEnumerable(Of Dictionary(Of String, Object)))  
                If source IsNot Nothing Then  
                    Dim firstItem = source.FirstOrDefault()  
     
                    If firstItem IsNot Nothing Then  
                        For Each key In firstItem  
                            Columns.Add(New DataColumn() With { _  
                             .ColumnName = key.Key, _  
                             .DataType = key.Value.[GetType]() _  
                            })  
                        Next  
     
                        For Each item In source  
                            Dim row = New SQLWiz.Data.myDataRow()  
     
                            For Each key In item  
                                row(key.Key) = key.Value  
                            Next  
                            Rows.Add(row)  
                        Next  
                    End If  
                End If  
            End Sub  
     
            Private m_columns As List(Of DataColumn) = Nothing  
            Public ReadOnly Property Columns() As List(Of DataColumn)  
                Get  
                    If m_columns Is Nothing Then  
                        m_columns = New List(Of DataColumn)()  
                    End If  
     
                    Return m_columns  
                End Get  
            End Property  
     
            Private m_rows As List(Of SQLWiz.Data.myDataRow) = Nothing  
            Public ReadOnly Property Rows() As List(Of SQLWiz.Data.myDataRow)  
                Get  
                    If m_rows Is Nothing Then  
                        m_rows = New List(Of SQLWiz.Data.myDataRow)()  
                    End If  
     
                    Return m_rows  
                End Get  
            End Property  
     
            Public Function NewRow() As Object  
                If queryable IsNot Nothing Then  
                    Return Activator.CreateInstance(queryable.ElementType)  
                End If  
     
                Return Nothing  
            End Function  
     
    #Region "IEnumerable Members"  
     
            Private queryable As IQueryable = Nothing 
            Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator  
                If queryable Is Nothing Then  
                    Dim type = ClassFactory.Instance.GetDynamicClass(Me.Columns.[Select](Function(c) New DynamicProperty(c.ColumnName, c.DataType)))  
                    Dim propertyInfos = type.GetProperties().ToList()  
     
                    Dim mylist = DirectCast(Activator.CreateInstance(GetType(List(Of )).MakeGenericType(type)), IList)  
                    For Each row In Me.Rows  
                        Dim item = Activator.CreateInstance(type)  
                        propertyInfos.ForEach(Sub(p) p.SetValue(item, row(p.Name), Nothing))  
                        mylist.Add(item)  
                    Next  
     
                    queryable = mylist.AsQueryable()  
                End If  
     
                Return queryable.GetEnumerator()  
            End Function  
    #End Region  
     
            Public Function ToList() As IList  
                Dim enumerator = GetEnumerator()  
                Dim list = DirectCast(Activator.CreateInstance(GetType(List(Of )).MakeGenericType(queryable.ElementType)), IList)  
                While enumerator.MoveNext()  
                    list.Add(enumerator.Current)  
                End While  
                Return list  
            End Function  
        End Class  
     
        Public Class DataColumn  
            Public Sub New()  
                DataType = GetType(Object)  
            End Sub  
     
            Public Property DataType() As Type  
                Get  
                    Return m_DataType  
                End Get  
                Set(ByVal value As Type)  
                    m_DataType = value 
                End Set  
            End Property  
            Private m_DataType As Type  
            Public Property ColumnName() As String  
                Get  
                    Return m_ColumnName  
                End Get  
                Set(ByVal value As String)  
                    m_ColumnName = value 
                End Set  
            End Property  
            Private m_ColumnName As String  
        End Class  
     
        Public Class myDataRow  
            Inherits Dictionary(Of String, Object)  
     
            '  
     
        End Class  
    End Namespace  
    '=======================================================  
    'Service provided by Telerik (www.telerik.com)  
    'Conversion powered by NRefactory.  
    'Twitter: @telerik, @toddanglin  
    'Facebook: facebook.com/telerik  
    '=======================================================  
     

    Dynamic.VB
    ''Copyright (C) Microsoft Corporation.  All rights reserved.  
     
    Imports System.Collections.Generic  
    Imports System.Text  
    Imports System.Linq  
    Imports System.Linq.Expressions  
    Imports System.Reflection  
    Imports System.Reflection.Emit  
    Imports System.Threading  
    Imports System.Dynamic  
    Imports System.Runtime.CompilerServices  
     
    Namespace SQLWiz.Dynamic  
        Module DynamicQueryable  
            Sub New()  
            End Sub  
            <Extension()> _  
            Public Function Where(Of T)(ByVal source As IQueryable(Of T), ByVal predicate As String, ByVal ParamArray values As Object()) As IQueryable(Of T)  
                Return DirectCast(Where(DirectCast(source, IQueryable), predicate, values), IQueryable(Of T))  
            End Function  
     
            <Extension()> _  
            Public Function Where(ByVal source As IQueryable, ByVal predicate As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If predicate Is Nothing Then  
                    Throw New ArgumentNullException("predicate")  
                End If  
                Dim lambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, GetType(Boolean), predicate, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Where", New Type() {source.ElementType}, source.Expression, Expression.Quote(lambda)))  
            End Function  
     
            <Extension()> _  
            Public Function [Select](ByVal source As IQueryable, ByVal selector As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If selector Is Nothing Then  
                    Throw New ArgumentNullException("selector")  
                End If  
                Dim lambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, selector, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Select", New Type() {source.ElementType, lambda.Body.Type}, source.Expression, Expression.Quote(lambda)))  
            End Function  
     
            <Extension()> _  
            Public Function OrderBy(Of T)(ByVal source As IQueryable(Of T), ByVal ordering As String, ByVal ParamArray values As Object()) As IQueryable(Of T)  
                Return DirectCast(OrderBy(DirectCast(source, IQueryable), ordering, values), IQueryable(Of T))  
            End Function  
     
            <Extension()> _  
            Public Function OrderBy(ByVal source As IQueryable, ByVal ordering As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If ordering Is Nothing Then  
                    Throw New ArgumentNullException("ordering")  
                End If  
                Dim parameters As ParameterExpression() = New ParameterExpression() {Expression.Parameter(source.ElementType, "")}  
                Dim parser As New ExpressionParser(parameters, ordering, values)  
                Dim orderings As IEnumerable(Of DynamicOrdering) = parser.ParseOrdering()  
                Dim queryExpr As Expression = source.Expression  
                Dim methodAsc As String = "OrderBy" 
                Dim methodDesc As String = "OrderByDescending" 
                For Each o As DynamicOrdering In orderings  
                    queryExpr = Expression.[Call](GetType(Queryable), If(o.Ascending, methodAsc, methodDesc), New Type() {source.ElementType, o.Selector.Type}, queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)))  
                    methodAsc = "ThenBy" 
                    methodDesc = "ThenByDescending" 
                Next  
                Return source.Provider.CreateQuery(queryExpr)  
            End Function  
     
            <Extension()> _  
            Public Function Take(ByVal source As IQueryable, ByVal count As Integer) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Take", New Type() {source.ElementType}, source.Expression, Expression.Constant(count)))  
            End Function  
     
            <Extension()> _  
            Public Function Skip(ByVal source As IQueryable, ByVal count As Integer) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "Skip", New Type() {source.ElementType}, source.Expression, Expression.Constant(count)))  
            End Function  
     
            <Extension()> _  
            Public Function GroupBy(ByVal source As IQueryable, ByVal keySelector As String, ByVal elementSelector As String, ByVal ParamArray values As Object()) As IQueryable  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                If keySelector Is Nothing Then  
                    Throw New ArgumentNullException("keySelector")  
                End If  
                If elementSelector Is Nothing Then  
                    Throw New ArgumentNullException("elementSelector")  
                End If  
                Dim keyLambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, keySelector, values)  
                Dim elementLambda As LambdaExpression = DynamicExpression.ParseLambda(source.ElementType, Nothing, elementSelector, values)  
                Return source.Provider.CreateQuery(Expression.[Call](GetType(Queryable), "GroupBy", New Type() {source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type}, source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda)))  
            End Function  
     
            <Extension()> _  
            Public Function Any(ByVal source As IQueryable) As Boolean  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return CBool(source.Provider.Execute(Expression.[Call](GetType(Queryable), "Any", New Type() {source.ElementType}, source.Expression)))  
            End Function  
     
            <Extension()> _  
            Public Function Count(ByVal source As IQueryable) As Integer  
                If source Is Nothing Then  
                    Throw New ArgumentNullException("source")  
                End If  
                Return CInt(source.Provider.Execute(Expression.[Call](GetType(Queryable), "Count", New Type() {source.ElementType}, source.Expression)))  
            End Function  
        End Module  
     
        Public MustInherit Class DynamicClass  
            Public Overrides Function ToString() As String  
                Dim props As PropertyInfo() = Me.[GetType]().GetProperties(BindingFlags.Instance Or BindingFlags.[Public])  
                Dim sb As New StringBuilder()  
                sb.Append("{")  
                For i As Integer = 0 To props.Length - 1  
                    If i > 0 Then  
                        sb.Append(", ")  
                    End If  
                    sb.Append(props(i).Name)  
                    sb.Append("=")  
                    sb.Append(props(i).GetValue(Me, Nothing))  
                Next  
                sb.Append("}")  
                Return sb.ToString()  
            End Function  
        End Class  
     
        Public Class DynamicProperty  
            Private m_name As String  
            Private m_type As Type  
     
            Public Sub New(ByVal name As String, ByVal type As Type)  
                If name Is Nothing Then  
                    Throw New ArgumentNullException("name")  
                End If  
                If type Is Nothing Then  
                    Throw New ArgumentNullException("type")  
                End If  
                Me.m_name = name  
                Me.m_type = type  
            End Sub  
     
            Public ReadOnly Property Name() As String  
                Get  
                    Return m_name  
                End Get  
            End Property  
     
            Public ReadOnly Property Type() As Type  
                Get  
                    Return m_type  
                End Get  
            End Property  
        End Class  
     
        Module DynamicExpression  
            Sub New()  
            End Sub  
            Public Function Parse(ByVal resultType As Type, ByVal expression As String, ByVal ParamArray values As Object()) As Expression  
                Dim parser As New ExpressionParser(Nothing, expression, values)  
                Return parser.Parse(resultType)  
            End Function  
     
            Public Function ParseLambda(ByVal itType As Type, ByVal resultType As Type, ByVal expression__1 As String, ByVal ParamArray values As Object()) As LambdaExpression  
                Return ParseLambda(New ParameterExpression() {Expression.Parameter(itType, "")}, resultType, expression__1, values)  
            End Function  
     
            Public Function ParseLambda(ByVal parameters As ParameterExpression(), ByVal resultType As Type, ByVal expression__1 As String, ByVal ParamArray values As Object()) As LambdaExpression  
                Dim parser As New ExpressionParser(parameters, expression__1, values)  
                Return Expression.Lambda(parser.Parse(resultType), parameters)  
            End Function  
     
            Public Function ParseLambda(Of T, S)(ByVal expression As String, ByVal ParamArray values As Object()) As Expression(Of Func(Of T, S))  
                Return DirectCast(ParseLambda(GetType(T), GetType(S), expression, values), Expression(Of Func(Of T, S)))  
            End Function  
     
            Public Function CreateClass(ByVal ParamArray properties As DynamicProperty()) As Type  
                Return ClassFactory.Instance.GetDynamicClass(properties)  
            End Function  
     
            Public Function CreateClass(ByVal properties As IEnumerable(Of DynamicProperty)) As Type  
                Return ClassFactory.Instance.GetDynamicClass(properties)  
            End Function  
        End Module  
     
        Friend Class DynamicOrdering  
            Public Selector As Expression  
            Public Ascending As Boolean  
        End Class  
     
        Friend Class Signature  
            Implements IEquatable(Of Signature)  
            Public properties As DynamicProperty()  
            Public hashCode As Integer  
     
            Public Sub New(ByVal properties As IEnumerable(Of DynamicProperty))  
                Me.properties = properties.ToArray()  
                hashCode = 0 
                For Each p As DynamicProperty In properties  
                    hashCodehashCode = hashCode Xor p.Name.GetHashCode() Xor p.Type.GetHashCode()  
                Next  
            End Sub  
     
            Public Overrides Function GetHashCode() As Integer  
                Return hashCode  
            End Function  
     
            Public Overrides Function Equals(ByVal obj As Object) As Boolean  
                Return If(TypeOf obj Is Signature, Equals(DirectCast(obj, Signature)), False)  
            End Function  
     
            Public Overloads Function Equals(ByVal other As Signature) As Boolean Implements IEquatable(Of Signature).Equals  
                If properties.Length <> other.properties.Length Then  
                    Return False  
                End If  
                For i As Integer = 0 To properties.Length - 1  
                    If properties(i).Name <> other.properties(i).Name OrElse properties(i).Type IsNot other.properties(i).Type Then  
                        Return False  
                    End If  
                Next  
                Return True  
            End Function  
        End Class  
     
        Friend Class ClassFactory  
            Public Shared ReadOnly Instance As New ClassFactory()  
     
            Shared Sub New()  
            End Sub  
            ' Trigger lazy initialization of static fields  
            Private [module] As ModuleBuilder  
            Private classes As Dictionary(Of Signature, Type)  
            Private classCount As Integer  
     
            Private Sub New()  
                Dim name As New AssemblyName("DynamicClasses")  
                Dim assembly As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run)  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                    New ReflectionPermission(PermissionState.Unrestricted).Assert()  
    #End If  
                Try  
                    [module] = assembly.DefineDynamicModule("Module")  
                Finally  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                    PermissionSet.RevertAssert()  
    #End If  
                End Try  
                classes = New Dictionary(Of Signature, Type)()  
            End Sub  
     
            Public Function GetDynamicClass(ByVal properties As IEnumerable(Of DynamicProperty)) As Type  
                Try  
                    Dim signature As New Signature(properties)  
                    Dim type As Type  
                    If Not classes.TryGetValue(signature, type) Then  
                        type = CreateDynamicClass(signature.properties)  
                        classes.Add(signature, type)  
                    End If  
                    Return type  
                Finally  
                End Try  
            End Function  
     
            Private Function CreateDynamicClass(ByVal properties As DynamicProperty()) As Type  
                Try  
                    Dim typeName As String = "DynamicClass" & (classCount + 1)  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                        New ReflectionPermission(PermissionState.Unrestricted).Assert()  
    #End If  
                    Try  
                        Dim tb As TypeBuilder = Me.[module].DefineType(typeName, TypeAttributes.[Class] Or TypeAttributes.[Public], GetType(DynamicClass))  
                        Dim fields As FieldInfo() = GenerateProperties(tb, properties)  
                        GenerateEquals(tb, fields)  
                        GenerateGetHashCode(tb, fields)  
                        Dim result As Type = tb.CreateType()  
                        classCount += 1  
                        Return result  
                    Finally  
    #If ENABLE_LINQ_PARTIAL_TRUST Then  
                        PermissionSet.RevertAssert()  
    #End If  
                    End Try  
                Finally  
                End Try  
            End Function  
     
            Private Function GenerateProperties(ByVal tb As TypeBuilder, ByVal properties As DynamicProperty()) As FieldInfo()  
                Dim fields As FieldInfo() = New FieldBuilder(properties.Length - 1) {}  
                For i As Integer = 0 To properties.Length - 1  
                    Dim dp As DynamicProperty = properties(i)  
                    Dim fb As FieldBuilder = tb.DefineField("_" & dp.Name, dp.Type, FieldAttributes.[Private])  
                    Dim pb As PropertyBuilder = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, Nothing)  
                    Dim mbGet As MethodBuilder = tb.DefineMethod("get_" & dp.Name, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, dp.Type, Type.EmptyTypes)  
                    Dim genGet As ILGenerator = mbGet.GetILGenerator()  
                    genGet.Emit(OpCodes.Ldarg_0)  
                    genGet.Emit(OpCodes.Ldfld, fb)  
                    genGet.Emit(OpCodes.Ret)  
                    Dim mbSet As MethodBuilder = tb.DefineMethod("set_" & dp.Name, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, Nothing, New Type() {dp.Type})  
                    Dim genSet As ILGenerator = mbSet.GetILGenerator()  
                    genSet.Emit(OpCodes.Ldarg_0)  
                    genSet.Emit(OpCodes.Ldarg_1)  
                    genSet.Emit(OpCodes.Stfld, fb)  
                    genSet.Emit(OpCodes.Ret)  
                    pb.SetGetMethod(mbGet)  
                    pb.SetSetMethod(mbSet)  
                    fields(i) = fb  
                Next  
                Return fields  
            End Function  
     
            Private Sub GenerateEquals(ByVal tb As TypeBuilder, ByVal fields As FieldInfo())  
                Dim mb As MethodBuilder = tb.DefineMethod("Equals", MethodAttributes.[Public] Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig, GetType(Boolean), New Type() {GetType(Object)})  
                Dim gen As ILGenerator = mb.GetILGenerator()  
                Dim other As LocalBuilder = gen.DeclareLocal(tb)  
                Dim [next] As Label = gen.DefineLabel()  
                gen.Emit(OpCodes.Ldarg_1)  
                gen.Emit(OpCodes.Isinst, tb)  
                gen.Emit(OpCodes.Stloc, other)  
                gen.Emit(OpCodes.Ldloc, other)  
                gen.Emit(OpCodes.Brtrue_S, [next])  
                gen.Emit(OpCodes.Ldc_I4_0)  
                gen.Emit(OpCodes.Ret)  
                gen.MarkLabel([next])  
                For Each field As FieldInfo In fields  
                    Dim ft As Type = field.FieldType  
                    Dim ct As Type = GetType(EqualityComparer(Of )).MakeGenericType(ft)  
                    [next] = gen.DefineLabel()  
                    gen.EmitCall(OpCodes.[Call], ct.GetMethod("get_Default"), Nothing)  
                    gen.Emit(OpCodes.Ldarg_0)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.Emit(OpCodes.Ldloc, other)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", New Type() {ft, ft}), Nothing)  
                    gen.Emit(OpCodes.Brtrue_S, [next])  
                    gen.Emit(OpCodes.Ldc_I4_0)  
                    gen.Emit(OpCodes.Ret)  
                    gen.MarkLabel([next])  
                Next  
                gen.Emit(OpCodes.Ldc_I4_1)  
                gen.Emit(OpCodes.Ret)  
            End Sub  
     
            Private Sub GenerateGetHashCode(ByVal tb As TypeBuilder, ByVal fields As FieldInfo())  
                Dim mb As MethodBuilder = tb.DefineMethod("GetHashCode", MethodAttributes.[Public] Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig, GetType(Integer), Type.EmptyTypes)  
                Dim gen As ILGenerator = mb.GetILGenerator()  
                gen.Emit(OpCodes.Ldc_I4_0)  
                For Each field As FieldInfo In fields  
                    Dim ft As Type = field.FieldType  
                    Dim ct As Type = GetType(EqualityComparer(Of )).MakeGenericType(ft)  
                    gen.EmitCall(OpCodes.[Call], ct.GetMethod("get_Default"), Nothing)  
                    gen.Emit(OpCodes.Ldarg_0)  
                    gen.Emit(OpCodes.Ldfld, field)  
                    gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", New Type() {ft}), Nothing)  
                    gen.Emit(OpCodes.[Xor])  
                Next  
                gen.Emit(OpCodes.Ret)  
            End Sub  
        End Class  
     
        Public NotInheritable Class ParseException  
            Inherits Exception  
            Private m_position As Integer  
     
            Public Sub New(ByVal message As String, ByVal position As Integer)  
                MyBase.New(message)  
                Me.m_position = position  
            End Sub  
     
            Public ReadOnly Property Position() As Integer  
                Get  
                    Return m_position  
                End Get  
            End Property  
     
            Public Overrides Function ToString() As String  
                Return String.Format(Res.ParseExceptionFormat, Message, m_position)  
            End Function  
        End Class  
     
        Friend Class ExpressionParser  
            Private Structure myToken  
                Public id As TokenId  
                Public text As String  
                Public pos As Integer  
            End Structure  
     
            Private Enum TokenId  
                Unknown  
                [End]  
                Identifier  
                StringLiteral  
                IntegerLiteral  
                RealLiteral  
                Exclamation  
                Percent  
                Amphersand  
                OpenParen  
                CloseParen  
                Asterisk  
                Plus  
                Comma  
                Minus  
                Dot  
                Slash  
                Colon  
                LessThan  
                Equal  
                GreaterThan  
                Question  
                OpenBracket  
                CloseBracket  
                Bar  
                ExclamationEqual  
                DoubleAmphersand  
                LessThanEqual  
                LessGreater  
                DoubleEqual  
                GreaterThanEqual  
                DoubleBar  
            End Enum  
     
            Private Interface ILogicalSignatures  
                Sub F(ByVal x As Boolean, ByVal y As Boolean)  
                Sub F(ByVal x As Global.System.Nullable(Of Boolean), ByVal y As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IArithmeticSignatures  
                Sub F(ByVal x As Integer, ByVal y As Integer)  
                Sub F(ByVal x As UInteger, ByVal y As UInteger)  
                Sub F(ByVal x As Long, ByVal y As Long)  
                Sub F(ByVal x As ULong, ByVal y As ULong)  
                Sub F(ByVal x As Single, ByVal y As Single)  
                Sub F(ByVal x As Double, ByVal y As Double)  
                Sub F(ByVal x As Decimal, ByVal y As Decimal)  
                Sub F(ByVal x As Global.System.Nullable(Of Integer), ByVal y As Global.System.Nullable(Of Integer))  
                Sub F(ByVal x As Global.System.Nullable(Of UInteger), ByVal y As Global.System.Nullable(Of UInteger))  
                Sub F(ByVal x As Global.System.Nullable(Of Long), ByVal y As Global.System.Nullable(Of Long))  
                Sub F(ByVal x As Global.System.Nullable(Of ULong), ByVal y As Global.System.Nullable(Of ULong))  
                Sub F(ByVal x As Global.System.Nullable(Of Single), ByVal y As Global.System.Nullable(Of Single))  
                Sub F(ByVal x As Global.System.Nullable(Of Double), ByVal y As Global.System.Nullable(Of Double))  
                Sub F(ByVal x As Global.System.Nullable(Of Decimal), ByVal y As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Private Interface IRelationalSignatures  
                Inherits IArithmeticSignatures  
                Overloads Sub F(ByVal x As String, ByVal y As String)  
                Overloads Sub F(ByVal x As Char, ByVal y As Char)  
                Overloads Sub F(ByVal x As DateTime, ByVal y As DateTime)  
                Overloads Sub F(ByVal x As TimeSpan, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of Char), ByVal y As Global.System.Nullable(Of Char))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of DateTime))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of TimeSpan), ByVal y As Global.System.Nullable(Of TimeSpan))  
            End Interface  
     
            Private Interface IEqualitySignatures  
                Inherits IRelationalSignatures  
                Overloads Sub F(ByVal x As Boolean, ByVal y As Boolean)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of Boolean), ByVal y As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IAddSignatures  
                Inherits IArithmeticSignatures  
                Overloads Sub F(ByVal x As DateTime, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As TimeSpan, ByVal y As TimeSpan)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of TimeSpan))  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of TimeSpan), ByVal y As Global.System.Nullable(Of TimeSpan))  
            End Interface  
     
            Private Interface ISubtractSignatures  
                Inherits IAddSignatures  
                Overloads Sub F(ByVal x As DateTime, ByVal y As DateTime)  
                Overloads Sub F(ByVal x As Global.System.Nullable(Of DateTime), ByVal y As Global.System.Nullable(Of DateTime))  
            End Interface  
     
            Private Interface INegationSignatures  
                Sub F(ByVal x As Integer)  
                Sub F(ByVal x As Long)  
                Sub F(ByVal x As Single)  
                Sub F(ByVal x As Double)  
                Sub F(ByVal x As Decimal)  
                Sub F(ByVal x As Global.System.Nullable(Of Integer))  
                Sub F(ByVal x As Global.System.Nullable(Of Long))  
                Sub F(ByVal x As Global.System.Nullable(Of Single))  
                Sub F(ByVal x As Global.System.Nullable(Of Double))  
                Sub F(ByVal x As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Private Interface INotSignatures  
                Sub F(ByVal x As Boolean)  
                Sub F(ByVal x As Global.System.Nullable(Of Boolean))  
            End Interface  
     
            Private Interface IEnumerableSignatures  
                Sub Where(ByVal predicate As Boolean)  
                Sub Any()  
                Sub Any(ByVal predicate As Boolean)  
                Sub All(ByVal predicate As Boolean)  
                Sub Count()  
                Sub Count(ByVal predicate As Boolean)  
                Sub Min(ByVal selector As Object)  
                Sub Max(ByVal selector As Object)  
                Sub Sum(ByVal selector As Integer)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Integer))  
                Sub Sum(ByVal selector As Long)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Long))  
                Sub Sum(ByVal selector As Single)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Single))  
                Sub Sum(ByVal selector As Double)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Double))  
                Sub Sum(ByVal selector As Decimal)  
                Sub Sum(ByVal selector As Global.System.Nullable(Of Decimal))  
                Sub Average(ByVal selector As Integer)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Integer))  
                Sub Average(ByVal selector As Long)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Long))  
                Sub Average(ByVal selector As Single)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Single))  
                Sub Average(ByVal selector As Double)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Double))  
                Sub Average(ByVal selector As Decimal)  
                Sub Average(ByVal selector As Global.System.Nullable(Of Decimal))  
            End Interface  
     
            Shared ReadOnly predefinedTypes As Type() = {GetType([Object]), GetType([Boolean]), GetType([Char]), GetType([String]), GetType([SByte]), GetType([Byte]), _  
             GetType(Int16), GetType(UInt16), GetType(Int32), GetType(UInt32), GetType(Int64), GetType(UInt64), _  
             GetType([Single]), GetType([Double]), GetType([Decimal]), GetType(DateTime), GetType(TimeSpan), GetType(Guid), _  
             GetType(Math), GetType(Convert)}  
     
            Shared ReadOnly trueLiteral As ExpressionExpression = Expression.Constant(True)  
            Shared ReadOnly falseLiteral As ExpressionExpression = Expression.Constant(False)  
            Shared ReadOnly nullLiteral As ExpressionExpression = Expression.Constant(Nothing)  
     
            Shared ReadOnly keywordIt As String = "it" 
            Shared ReadOnly keywordIif As String = "iif" 
            Shared ReadOnly keywordNew As String = "new" 
     
            Shared keywords As Dictionary(Of String, Object)  
     
            Private symbols As Dictionary(Of String, Object)  
            Private externals As IDictionary(Of String, Object)  
            Private literals As Dictionary(Of Expression, String)  
            Private it As ParameterExpression  
            Private text As String  
            Private textPos As Integer  
            Private textLen As Integer  
            Private ch As Char  
            Private varToken As myToken  
     
            Public Sub New(ByVal parameters As ParameterExpression(), ByVal expression As String, ByVal values As Object())  
                If expression Is Nothing Then  
                    Throw New ArgumentNullException("expression")  
                End If  
                If keywords Is Nothing Then  
                    keywords = CreateKeywords()  
                End If  
                symbols = New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)  
                literals = New Dictionary(Of Expression, String)()  
                If parameters IsNot Nothing Then  
                    ProcessParameters(parameters)  
                End If  
                If values IsNot Nothing Then  
                    ProcessValues(values)  
                End If  
                text = expression 
                texttextLen = text.Length  
                SetTextPos(0)  
                NextToken()  
            End Sub  
     
            Private Sub ProcessParameters(ByVal parameters As ParameterExpression())  
                For Each pe As ParameterExpression In parameters  
                    If Not [String].IsNullOrEmpty(pe.Name) Then  
                        AddSymbol(pe.Name, pe)  
                    End If  
                Next  
                If parameters.Length = 1 AndAlso [String].IsNullOrEmpty(parameters(0).Name) Then  
                    it = parameters(0)  
                End If  
            End Sub  
     
            Private Sub ProcessValues(ByVal values As Object())  
                For i As Integer = 0 To values.Length - 1  
                    Dim value As Object = values(i)  
                    If i = values.Length - 1 AndAlso TypeOf value Is IDictionary(Of String, Object) Then  
                        externals = DirectCast(value, IDictionary(Of String, Object))  
                    Else  
                        AddSymbol("@" & i.ToString(Globalization.CultureInfo.InvariantCulture), value)  
                    End If  
                Next  
            End Sub  
     
            Private Sub AddSymbol(ByVal name As String, ByVal value As Object)  
                If symbols.ContainsKey(name) Then  
                    Throw ParseError(Res.DuplicateIdentifier, name)  
                End If  
                symbols.Add(name, value)  
            End Sub  
     
            Public Function Parse(ByVal resultType As Type) As Expression  
                Dim exprPos As Integer = varToken.pos  
                Dim expr As Expression = ParseExpression()  
                If resultType IsNot Nothing Then  
                    If (InlineAssignHelper(expr, PromoteExpression(expr, resultType, True))) Is Nothing Then  
                        Throw ParseError(exprPos, Res.ExpressionTypeMismatch, GetTypeName(resultType))  
                    End If  
                End If  
                ValidateToken(TokenId.[End], Res.SyntaxError)  
                Return expr  
            End Function  
     
            '#Pragma warning disable 0219  
            Public Function ParseOrdering() As IEnumerable(Of DynamicOrdering)  
                Dim orderings As New List(Of DynamicOrdering)()  
                While True  
                    Dim expr As Expression = ParseExpression()  
                    Dim ascending As Boolean = True 
                    If TokenIdentifierIs("asc") OrElse TokenIdentifierIs("ascending") Then  
                        NextToken()  
                    ElseIf TokenIdentifierIs("desc") OrElse TokenIdentifierIs("descending") Then  
                        NextToken()  
                        ascending = False 
                    End If  
                    orderings.Add(New DynamicOrdering() With { _  
                      .Selector = expr, _  
                      .Ascending = ascending _  
                    })  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                ValidateToken(TokenId.[End], Res.SyntaxError)  
                Return orderings  
            End Function  
            '#Pragma warning restore 0219  
     
            ' ?: operator  
            Private Function ParseExpression() As Expression  
                Dim errorPos As Integer = varToken.pos  
                Dim expr As Expression = ParseLogicalOr()  
                If varToken.id = TokenId.Question Then  
                    NextToken()  
                    Dim expr1 As Expression = ParseExpression()  
                    ValidateToken(TokenId.Colon, Res.ColonExpected)  
                    NextToken()  
                    Dim expr2 As Expression = ParseExpression()  
                    expr = GenerateConditional(expr, expr1, expr2, errorPos)  
                End If  
                Return expr  
            End Function  
     
            ' ||, or operator  
            Private Function ParseLogicalOr() As Expression  
                Dim left As Expression = ParseLogicalAnd()  
                While varToken.id = TokenId.DoubleBar OrElse TokenIdentifierIs("or")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseLogicalAnd()  
                    CheckAndPromoteOperands(GetType(ILogicalSignatures), op.text, left, right, op.pos)  
                    left = Expression.[OrElse](left, right)  
                End While  
                Return left  
            End Function  
     
            ' &&, and operator  
            Private Function ParseLogicalAnd() As Expression  
                Dim left As Expression = ParseComparison()  
                While varToken.id = TokenId.DoubleAmphersand OrElse TokenIdentifierIs("and")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseComparison()  
                    CheckAndPromoteOperands(GetType(ILogicalSignatures), op.text, left, right, op.pos)  
                    left = Expression.[AndAlso](left, right)  
                End While  
                Return left  
            End Function  
     
            ' =, ==, !=, <>, >>=, <<= operators  
            Private Function ParseComparison() As Expression  
                Dim left As Expression = ParseAdditive()  
                While varToken.id = TokenId.Equal OrElse varToken.id = TokenId.DoubleEqual OrElse varToken.id = TokenId.ExclamationEqual OrElse varToken.id = TokenId.LessGreater OrElse varToken.id = TokenId.GreaterThan OrElse varToken.id = TokenId.GreaterThanEqual OrElse varToken.id = TokenId.LessThan OrElse varToken.id = TokenId.LessThanEqual  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseAdditive()  
                    Dim isEquality As Boolean = op.id = TokenId.Equal OrElse op.id = TokenId.DoubleEqual OrElse op.id = TokenId.ExclamationEqual OrElse op.id = TokenId.LessGreater  
                    If isEquality AndAlso Not left.Type.IsValueType AndAlso Not right.Type.IsValueType Then  
                        If Not left.Type.Equals(right.Type) Then  
                            If left.Type.IsAssignableFrom(right.Type) Then  
                                right = Expression.Convert(right, left.Type)  
                            ElseIf right.Type.IsAssignableFrom(left.Type) Then  
                                left = Expression.Convert(left, right.Type)  
                            Else  
                                Throw IncompatibleOperandsError(op.text, left, right, op.pos)  
                            End If  
                        End If  
                    ElseIf IsEnumType(left.Type) OrElse IsEnumType(right.Type) Then  
                        If Not left.Type.Equals(right.Type) Then  
                            Dim e As Expression  
                            If (InlineAssignHelper(e, PromoteExpression(right, left.Type, True))) IsNot Nothing Then  
                                right = e 
                            ElseIf (InlineAssignHelper(e, PromoteExpression(left, right.Type, True))) IsNot Nothing Then  
                                left = e  
                            Else  
                                Throw IncompatibleOperandsError(op.text, left, right, op.pos)  
                            End If  
                        End If  
                    Else  
                        CheckAndPromoteOperands(If(isEquality, GetType(IEqualitySignatures), GetType(IRelationalSignatures)), op.text, left, right, op.pos)  
                    End If  
                    Select Case op.id  
                        Case TokenId.Equal, TokenId.DoubleEqual  
                            left = GenerateEqual(left, right)  
                            Exit Select  
                        Case TokenId.ExclamationEqual, TokenId.LessGreater  
                            left = GenerateNotEqual(left, right)  
                            Exit Select  
                        Case TokenId.GreaterThan  
                            left = GenerateGreaterThan(left, right)  
                            Exit Select  
                        Case TokenId.GreaterThanEqual  
                            left = GenerateGreaterThanEqual(left, right)  
                            Exit Select  
                        Case TokenId.LessThan  
                            left = GenerateLessThan(left, right)  
                            Exit Select  
                        Case TokenId.LessThanEqual  
                            left = GenerateLessThanEqual(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' +, -, & operators  
            Private Function ParseAdditive() As Expression  
                Dim left As Expression = ParseMultiplicative()  
                While varToken.id = TokenId.Plus OrElse varToken.id = TokenId.Minus OrElse varToken.id = TokenId.Amphersand  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseMultiplicative()  
                    Select Case op.id  
                        Case TokenId.Plus  
                            If left.Type.Equals(GetType(String)) OrElse right.Type.Equals(GetType(String)) Then  
                                left = GenerateStringConcat(left, right)  
                                Exit Select  
                            End If  
                            CheckAndPromoteOperands(GetType(IAddSignatures), op.text, left, right, op.pos)  
                            left = GenerateAdd(left, right)  
                            Exit Select  
                        Case TokenId.Minus  
                            CheckAndPromoteOperands(GetType(ISubtractSignatures), op.text, left, right, op.pos)  
                            left = GenerateSubtract(left, right)  
                            Exit Select  
                        Case TokenId.Amphersand  
                            left = GenerateStringConcat(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' *, /, %, mod operators  
            Private Function ParseMultiplicative() As Expression  
                Dim left As Expression = ParseUnary()  
                While varToken.id = TokenId.Asterisk OrElse varToken.id = TokenId.Slash OrElse varToken.id = TokenId.Percent OrElse TokenIdentifierIs("mod")  
                    Dim op As myToken = varToken 
                    NextToken()  
                    Dim right As Expression = ParseUnary()  
                    CheckAndPromoteOperands(GetType(IArithmeticSignatures), op.text, left, right, op.pos)  
                    Select Case op.id  
                        Case TokenId.Asterisk  
                            left = Expression.Multiply(left, right)  
                            Exit Select  
                        Case TokenId.Slash  
                            left = Expression.Divide(left, right)  
                            Exit Select  
                        Case TokenId.Percent, TokenId.Identifier  
                            left = Expression.Modulo(left, right)  
                            Exit Select  
                    End Select  
                End While  
                Return left  
            End Function  
     
            ' -, !, not unary operators  
            Private Function ParseUnary() As Expression  
                If varToken.id = TokenId.Minus OrElse varToken.id = TokenId.Exclamation OrElse TokenIdentifierIs("not") Then  
                    Dim op As myToken = varToken 
                    NextToken()  
                    If op.id = TokenId.Minus AndAlso (varToken.id = TokenId.IntegerLiteral OrElse varToken.id = TokenId.RealLiteral) Then  
                        varToken.text = "-" & varToken.text  
                        varToken.pos = op.pos  
                        Return ParsePrimary()  
                    End If  
                    Dim expr As Expression = ParseUnary()  
                    If op.id = TokenId.Minus Then  
                        CheckAndPromoteOperand(GetType(INegationSignatures), op.text, expr, op.pos)  
                        expr = Expression.Negate(expr)  
                    Else  
                        CheckAndPromoteOperand(GetType(INotSignatures), op.text, expr, op.pos)  
                        expr = Expression.[Not](expr)  
                    End If  
                    Return expr  
                End If  
                Return ParsePrimary()  
            End Function  
     
            Private Function ParsePrimary() As Expression  
                Dim expr As Expression = ParsePrimaryStart()  
                While True  
                    If varToken.id = TokenId.Dot Then  
                        NextToken()  
                        expr = ParseMemberAccess(Nothing, expr)  
                    ElseIf varToken.id = TokenId.OpenBracket Then  
                        expr = ParseElementAccess(expr)  
                    Else  
                        Exit While  
                    End If  
                End While  
                Return expr  
            End Function  
     
            Private Function ParsePrimaryStart() As Expression  
                Select Case varToken.id  
                    Case TokenId.Identifier  
                        Return ParseIdentifier()  
                    Case TokenId.StringLiteral  
                        Return ParseStringLiteral()  
                    Case TokenId.IntegerLiteral  
                        Return ParseIntegerLiteral()  
                    Case TokenId.RealLiteral  
                        Return ParseRealLiteral()  
                    Case TokenId.OpenParen  
                        Return ParseParenExpression()  
                    Case Else  
                        Throw ParseError(Res.ExpressionExpected)  
                End Select  
            End Function  
     
            Private Function ParseStringLiteral() As Expression  
                ValidateToken(TokenId.StringLiteral)  
                Dim quote As Char = varToken.text(0)  
                Dim s As String = varToken.text.Substring(1, varToken.text.Length - 2)  
                Dim start As Integer = 0 
                While True  
                    Dim i As Integer = s.IndexOf(quote, start)  
                    If i < 0 Then  
                        Exit While  
                    End If  
                    ss = s.Remove(i, 1)  
                    start = i + 1  
                End While  
                If quote = "'"c Then  
                    If s.Length <> 1 Then  
                        Throw ParseError(Res.InvalidCharacterLiteral)  
                    End If  
                    NextToken()  
                    Return CreateLiteral(s(0), s)  
                End If  
                NextToken()  
                Return CreateLiteral(s, s)  
            End Function  
     
            Private Function ParseIntegerLiteral() As Expression  
                ValidateToken(TokenId.IntegerLiteral)  
                Dim text As String = varToken.text  
                If text(0) <> "-"c Then  
                    Dim value As ULong  
                    If Not UInt64.TryParse(text, value) Then  
                        Throw ParseError(Res.InvalidIntegerLiteral, text)  
                    End If  
                    NextToken()  
                    If value <= CULng(Int32.MaxValue) Then  
                        Return CreateLiteral(CInt(value), text)  
                    End If  
                    If value <= CULng(UInt32.MaxValue) Then  
                        Return CreateLiteral(CUInt(value), text)  
                    End If  
                    If value <= CULng(Int64.MaxValue) Then  
                        Return CreateLiteral(CLng(value), text)  
                    End If  
                    Return CreateLiteral(value, text)  
                Else  
                    Dim value As Long  
                    If Not Int64.TryParse(text, value) Then  
                        Throw ParseError(Res.InvalidIntegerLiteral, text)  
                    End If  
                    NextToken()  
                    If value >= Int32.MinValue AndAlso value <= Int32.MaxValue Then  
                        Return CreateLiteral(CInt(value), text)  
                    End If  
                    Return CreateLiteral(value, text)  
                End If  
            End Function  
     
            Private Function ParseRealLiteral() As Expression  
                ValidateToken(TokenId.RealLiteral)  
                Dim text As String = varToken.text  
                Dim value As Object = Nothing 
                Dim last As Char = text(text.Length - 1)  
                If last = "F"c OrElse last = "f"c Then  
                    Dim f As Single  
                    If [Single].TryParse(text.Substring(0, text.Length - 1), f) Then  
                        value = f 
                    End If  
                Else  
                    Dim d As Double  
                    If [Double].TryParse(text, d) Then  
                        value = d 
                    End If  
                End If  
                If value Is Nothing Then  
                    Throw ParseError(Res.InvalidRealLiteral, text)  
                End If  
                NextToken()  
                Return CreateLiteral(value, text)  
            End Function  
     
            Private Function CreateLiteral(ByVal value As Object, ByVal text As String) As Expression  
                Dim expr As ConstantExpression = Expression.Constant(value)  
                literals.Add(expr, text)  
                Return expr  
            End Function  
     
            Private Function ParseParenExpression() As Expression  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim e As Expression = ParseExpression()  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected)  
                NextToken()  
                Return e  
            End Function  
     
            Private Function ParseIdentifier() As Expression  
                ValidateToken(TokenId.Identifier)  
                Dim value As Object  
                If keywords.TryGetValue(varToken.text, value) Then  
                    If TypeOf value Is Type Then  
                        Return ParseTypeAccess(DirectCast(value, Type))  
                    End If  
                    If value Is DirectCast(keywordIt, Object) Then  
                        Return ParseIt()  
                    End If  
                    If value Is DirectCast(keywordIif, Object) Then  
                        Return ParseIif()  
                    End If  
                    If value Is DirectCast(keywordNew, Object) Then  
                        Return ParseNew()  
                    End If  
                    NextToken()  
                    Return DirectCast(value, Expression)  
                End If  
                If symbols.TryGetValue(varToken.text, value) OrElse externals IsNot Nothing AndAlso externals.TryGetValue(varToken.text, value) Then  
                    Dim expr As Expression = TryCast(value, Expression)  
                    If expr Is Nothing Then  
                        expr = Expression.Constant(value)  
                    Else  
                        Dim lambda As LambdaExpression = TryCast(expr, LambdaExpression)  
                        If lambda IsNot Nothing Then  
                            Return ParseLambdaInvocation(lambda)  
                        End If  
                    End If  
                    NextToken()  
                    Return expr  
                End If  
                If it IsNot Nothing Then  
                    Return ParseMemberAccess(Nothing, it)  
                End If  
                Throw ParseError(Res.UnknownIdentifier, varToken.text)  
            End Function  
     
            Private Function ParseIt() As Expression  
                If it Is Nothing Then  
                    Throw ParseError(Res.NoItInScope)  
                End If  
                NextToken()  
                Return it  
            End Function  
     
            Private Function ParseIif() As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                Dim args As Expression() = ParseArgumentList()  
                If args.Length <> 3 Then  
                    Throw ParseError(errorPos, Res.IifRequiresThreeArgs)  
                End If  
                Return GenerateConditional(args(0), args(1), args(2), errorPos)  
            End Function  
     
            Private Function GenerateConditional(ByVal test As Expression, ByVal expr1 As Expression, ByVal expr2 As Expression, ByVal errorPos As Integer) As Expression  
                If Not test.Type.Equals(GetType(Boolean)) Then  
                    Throw ParseError(errorPos, Res.FirstExprMustBeBool)  
                End If  
                If Not expr1.Type.Equals(expr2.Type) Then  
                    Dim expr1as2 As Expression = If(Not expr2.Equals(nullLiteral), PromoteExpression(expr1, expr2.Type, True), Nothing)  
                    Dim expr2as1 As Expression = If(Not expr2.Equals(nullLiteral), PromoteExpression(expr2, expr1.Type, True), Nothing)  
                    If expr1as2 IsNot Nothing AndAlso expr2as1 Is Nothing Then  
                        expr1 = expr1as2 
                    ElseIf expr2as1 IsNot Nothing AndAlso expr1as2 Is Nothing Then  
                        expr2 = expr2as1 
                    Else  
                        Dim type1 As String = If(Not expr2.Equals(nullLiteral), expr1.Type.Name, "null")  
                        Dim type2 As String = If(Not expr2.Equals(nullLiteral), expr2.Type.Name, "null")  
                        If expr1as2 IsNot Nothing AndAlso expr2as1 IsNot Nothing Then  
                            Throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2)  
                        End If  
                        Throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2)  
                    End If  
                End If  
                Return Expression.Condition(test, expr1, expr2)  
            End Function  
     
            Private Function ParseNew() As Expression  
                NextToken()  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim properties As New List(Of DynamicProperty)()  
                Dim expressions As New List(Of Expression)()  
                While True  
                    Dim exprPos As Integer = varToken.pos  
                    Dim expr As Expression = ParseExpression()  
                    Dim propName As String  
                    If TokenIdentifierIs("as") Then  
                        NextToken()  
                        propName = GetIdentifier()  
                        NextToken()  
                    Else  
                        Dim [me] As MemberExpression = TryCast(expr, MemberExpression)  
                        If [me] Is Nothing Then  
                            Throw ParseError(exprPos, Res.MissingAsClause)  
                        End If  
                        propName = [me].Member.Name  
                    End If  
                    expressions.Add(expr)  
                    properties.Add(New DynamicProperty(propName, expr.Type))  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)  
                NextToken()  
                Dim type As Type = DynamicExpression.CreateClass(properties)  
                Dim bindings As MemberBinding() = New MemberBinding(properties.Count - 1) {}  
                For i As Integer = 0 To bindings.Length - 1  
                    bindings(i) = Expression.Bind(type.GetProperty(properties(i).Name), expressions(i))  
                Next  
                Return Expression.MemberInit(Expression.[New](type), bindings)  
            End Function  
     
            Private Function ParseLambdaInvocation(ByVal lambda As LambdaExpression) As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                Dim args As Expression() = ParseArgumentList()  
                Dim method As MethodBase  
                If FindMethod(lambda.Type, "Invoke", False, args, method) <> 1 Then  
                    Throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda)  
                End If  
                Return Expression.Invoke(lambda, args)  
            End Function  
     
            Private Function ParseTypeAccess(ByVal type As Type) As Expression  
                Dim errorPos As Integer = varToken.pos  
                NextToken()  
                If varToken.id = TokenId.Question Then  
                    If Not type.IsValueType OrElse IsNullableType(type) Then  
                        Throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type))  
                    End If  
                    type = GetType(Nullable(Of )).MakeGenericType(type)  
                    NextToken()  
                End If  
                If varToken.id = TokenId.OpenParen Then  
                    Dim args As Expression() = ParseArgumentList()  
                    Dim method As MethodBase  
                    Select Case FindBestMethod(type.GetConstructors(), args, method)  
                        Case 0  
                            If args.Length = 1 Then  
                                Return GenerateConversion(args(0), type, errorPos)  
                            End If  
                            Throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type))  
                        Case 1  
                            Return Expression.[New](DirectCast(method, ConstructorInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type))  
                    End Select  
                End If  
                ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected)  
                NextToken()  
                Return ParseMemberAccess(type, Nothing)  
            End Function  
     
            Private Function GenerateConversion(ByVal expr As Expression, ByVal type As Type, ByVal errorPos As Integer) As Expression  
                Dim exprType As Type = expr.Type  
                If exprType Is type Then  
                    Return expr  
                End If  
                If exprType.IsValueType AndAlso type.IsValueType Then  
                    If (IsNullableType(exprType) OrElse IsNullableType(type)) AndAlso GetNonNullableType(exprType) Is GetNonNullableType(type) Then  
                        Return Expression.Convert(expr, type)  
                    End If  
                    If (IsNumericType(exprType) OrElse IsEnumType(exprType)) AndAlso (IsNumericType(type)) OrElse IsEnumType(type) Then  
                        Return Expression.ConvertChecked(expr, type)  
                    End If  
                End If  
                If exprType.IsAssignableFrom(type) OrElse type.IsAssignableFrom(exprType) OrElse exprType.IsInterface OrElse type.IsInterface Then  
                    Return Expression.Convert(expr, type)  
                End If  
                Throw ParseError(errorPos, Res.CannotConvertValue, GetTypeName(exprType), GetTypeName(type))  
            End Function  
     
            Private Function ParseMemberAccess(ByVal type As Type, ByVal instance As Expression) As Expression  
                If instance IsNot Nothing Then  
                    type = instance.Type  
                End If  
                Dim errorPos As Integer = varToken.pos  
                Dim id As String = GetIdentifier()  
                NextToken()  
                If varToken.id = TokenId.OpenParen Then  
                    If instance IsNot Nothing AndAlso type IsNot GetType(String) Then  
                        Dim enumerableType As Type = FindGenericType(GetType(IEnumerable(Of )), type)  
                        If enumerableType IsNot Nothing Then  
                            Dim elementType As Type = enumerableType.GetGenericArguments()(0)  
                            Return ParseAggregate(instance, elementType, id, errorPos)  
                        End If  
                    End If  
                    Dim args As Expression() = ParseArgumentList()  
                    Dim mb As MethodBase  
                    Select Case FindMethod(type, id, instance Is Nothing, args, mb)  
                        Case 0  
                            Throw ParseError(errorPos, Res.NoApplicableMethod, id, GetTypeName(type))  
                        Case 1  
                            Dim method As MethodInfo = DirectCast(mb, MethodInfo)  
                            If Not IsPredefinedType(method.DeclaringType) Then  
                                Throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType))  
                            End If  
                            If method.ReturnType Is GetType(Void) Then  
                                Throw ParseError(errorPos, Res.MethodIsVoid, id, GetTypeName(method.DeclaringType))  
                            End If  
                            Return Expression.[Call](instance, DirectCast(method, MethodInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousMethodInvocation, id, GetTypeName(type))  
                    End Select  
                Else  
                    Dim member As MemberInfo = FindPropertyOrField(type, id, instance Is Nothing)  
                    If member Is Nothing Then  
                        Throw ParseError(errorPos, Res.UnknownPropertyOrField, id, GetTypeName(type))  
                    End If  
                    Return If(TypeOf member Is PropertyInfo, Expression.[Property](instance, DirectCast(member, PropertyInfo)), Expression.Field(instance, DirectCast(member, FieldInfo)))  
                End If  
            End Function  
     
            Private Shared Function FindGenericType(ByVal generic As Type, ByVal type As Type) As Type  
                While type IsNot Nothing AndAlso type IsNot GetType(Object)  
                    If type.IsGenericType AndAlso type.GetGenericTypeDefinition() Is generic Then  
                        Return type  
                    End If  
                    If generic.IsInterface Then  
                        For Each intfType As Type In type.GetInterfaces()  
                            Dim found As Type = FindGenericType(generic, intfType)  
                            If found IsNot Nothing Then  
                                Return found  
                            End If  
                        Next  
                    End If  
                    typetype = type.BaseType  
                End While  
                Return Nothing  
            End Function  
     
            Private Function ParseAggregate(ByVal instance As Expression, ByVal elementType As Type, ByVal methodName As String, ByVal errorPos As Integer) As Expression  
                Dim outerIt As ParameterExpression = it 
                Dim innerIt As ParameterExpression = Expression.Parameter(elementType, "")  
                it = innerIt 
                Dim args As Expression() = ParseArgumentList()  
                it = outerIt 
                Dim signature As MethodBase  
                If FindMethod(GetType(IEnumerableSignatures), methodName, False, args, signature) <> 1 Then  
                    Throw ParseError(errorPos, Res.NoApplicableAggregate, methodName)  
                End If  
                Dim typeArgs As Type()  
                If signature.Name = "Min" OrElse signature.Name = "Max" Then  
                    typeArgs = New Type() {elementType, args(0).Type}  
                Else  
                    typeArgs = New Type() {elementType}  
                End If  
                If args.Length = 0 Then  
                    args = New Expression() {instance}  
                Else  
                    args = New Expression() {instance, Expression.Lambda(args(0), innerIt)}  
                End If  
                Return Expression.[Call](GetType(Enumerable), signature.Name, typeArgs, args)  
            End Function  
     
            Private Function ParseArgumentList() As Expression()  
                ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)  
                NextToken()  
                Dim args As Expression() = If(varToken.id <> TokenId.CloseParen, ParseArguments(), New Expression(-1) {})  
                ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)  
                NextToken()  
                Return args  
            End Function  
     
            Private Function ParseArguments() As Expression()  
                Dim argList As New List(Of Expression)()  
                While True  
                    argList.Add(ParseExpression())  
                    If varToken.id <> TokenId.Comma Then  
                        Exit While  
                    End If  
                    NextToken()  
                End While  
                Return argList.ToArray()  
            End Function  
     
            Private Function ParseElementAccess(ByVal expr As Expression) As Expression  
                Dim errorPos As Integer = varToken.pos  
                ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected)  
                NextToken()  
                Dim args As Expression() = ParseArguments()  
                ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected)  
                NextToken()  
                If expr.Type.IsArray Then  
                    If expr.Type.GetArrayRank() <> 1 OrElse args.Length <> 1 Then  
                        Throw ParseError(errorPos, Res.CannotIndexMultiDimArray)  
                    End If  
                    Dim index As Expression = PromoteExpression(args(0), GetType(Integer), True)  
                    If index Is Nothing Then  
                        Throw ParseError(errorPos, Res.InvalidIndex)  
                    End If  
                    Return Expression.ArrayIndex(expr, index)  
                Else  
                    Dim mb As MethodBase  
                    Select Case FindIndexer(expr.Type, args, mb)  
                        Case 0  
                            Throw ParseError(errorPos, Res.NoApplicableIndexer, GetTypeName(expr.Type))  
                        Case 1  
                            Return Expression.[Call](expr, DirectCast(mb, MethodInfo), args)  
                        Case Else  
                            Throw ParseError(errorPos, Res.AmbiguousIndexerInvocation, GetTypeName(expr.Type))  
                    End Select  
                End If  
            End Function  
     
            Private Shared Function IsPredefinedType(ByVal type As Type) As Boolean  
                For Each t As Type In predefinedTypes  
                    If t Is type Then  
                        Return True  
                    End If  
                Next  
                Return False  
            End Function  
     
            Private Shared Function IsNullableType(ByVal type As Type) As Boolean  
                Return type.IsGenericType AndAlso type.GetGenericTypeDefinition() Is GetType(Nullable(Of ))  
            End Function  
     
            Private Shared Function GetNonNullableType(ByVal type As Type) As Type  
                Return If(IsNullableType(type), type.GetGenericArguments()(0), type)  
            End Function  
     
            Private Shared Function GetTypeName(ByVal type As Type) As String  
                Dim baseType As Type = GetNonNullableType(type)  
                Dim s As String = baseType.Name  
                If type IsNot baseType Then  
                    s += "?"c  
                End If  
                Return s  
            End Function  
     
            Private Shared Function IsNumericType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) <> 0  
            End Function  
     
            Private Shared Function IsSignedIntegralType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) = 2  
            End Function  
     
            Private Shared Function IsUnsignedIntegralType(ByVal type As Type) As Boolean  
                Return GetNumericTypeKind(type) = 3  
            End Function  
     
            Private Shared Function GetNumericTypeKind(ByVal type__1 As Type) As Integer  
                type__1 = GetNonNullableType(type__1)  
                If type__1.IsEnum Then  
                    Return 0  
                End If  
                Select Case Type.GetTypeCode(type__1)  
                    Case TypeCode.[Char], TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                        Return 1  
                    Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64  
                        Return 2  
                    Case TypeCode.[Byte], TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64  
                        Return 3  
                    Case Else  
                        Return 0  
                End Select  
            End Function  
     
            Private Shared Function IsEnumType(ByVal type As Type) As Boolean  
                Return GetNonNullableType(type).IsEnum  
            End Function  
     
            Private Sub CheckAndPromoteOperand(ByVal signatures As Type, ByVal opName As String, ByRef expr As Expression, ByVal errorPos As Integer)  
                Dim args As Expression() = New Expression() {expr}  
                Dim method As MethodBase  
                If FindMethod(signatures, "F", False, args, method) <> 1 Then  
                    Throw ParseError(errorPos, Res.IncompatibleOperand, opName, GetTypeName(args(0).Type))  
                End If  
                expr = args(0)  
            End Sub  
     
            Private Sub CheckAndPromoteOperands(ByVal signatures As Type, ByVal opName As String, ByRef left As Expression, ByRef right As Expression, ByVal errorPos As Integer)  
                Dim args As Expression() = New Expression() {left, right}  
                Dim method As MethodBase  
                If FindMethod(signatures, "F", False, args, method) <> 1 Then  
                    Throw IncompatibleOperandsError(opName, left, right, errorPos)  
                End If  
                left = args(0)  
                right = args(1)  
            End Sub  
     
            Private Function IncompatibleOperandsError(ByVal opName As String, ByVal left As Expression, ByVal right As Expression, ByVal pos As Integer) As Exception  
                Return ParseError(pos, Res.IncompatibleOperands, opName, GetTypeName(left.Type), GetTypeName(right.Type))  
            End Function  
     
            Private Function FindPropertyOrField(ByVal type__1 As Type, ByVal memberName As String, ByVal staticAccess As Boolean) As MemberInfo  
                Dim flags As BindingFlagsBindingFlags = BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or (If(staticAccess, BindingFlags.[Static], BindingFlags.Instance))  
                For Each t As Type In SelfAndBaseTypes(type__1)  
                    Dim members As MemberInfo() = t.FindMembers(MemberTypes.[Property] Or MemberTypes.Field, flags, Type.FilterNameIgnoreCase, memberName)  
                    If members.Length <> 0 Then  
                        Return members(0)  
                    End If  
                Next  
                Return Nothing  
            End Function  
     
            Private Function FindMethod(ByVal type__1 As Type, ByVal methodName As String, ByVal staticAccess As Boolean, ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                Dim flags As BindingFlagsBindingFlags = BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or (If(staticAccess, BindingFlags.[Static], BindingFlags.Instance))  
                For Each t As Type In SelfAndBaseTypes(type__1)  
                    Dim members As MemberInfo() = t.FindMembers(MemberTypes.Method, flags, Type.FilterNameIgnoreCase, methodName)  
                    Dim count As Integer = FindBestMethod(members.Cast(Of MethodBase)(), args, method)  
                    If count <> 0 Then  
                        Return count  
                    End If  
                Next  
                method = Nothing 
                Return 0  
            End Function  
     
            Private Function FindIndexer(ByVal type As Type, ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                For Each t As Type In SelfAndBaseTypes(type)  
                    Dim members As MemberInfo() = t.GetDefaultMembers()  
                    If members.Length <> 0 Then  
                        Dim methods As IEnumerable(Of MethodBase) = members.OfType(Of PropertyInfo)().[Select](Function(p) DirectCast(p.GetGetMethod(), MethodBase)).Where(Function(m) m IsNot Nothing)  
                        Dim count As Integer = FindBestMethod(methods, args, method)  
                        If count <> 0 Then  
                            Return count  
                        End If  
                    End If  
                Next  
                method = Nothing 
                Return 0  
            End Function  
     
            Private Shared Function SelfAndBaseTypes(ByVal type As Type) As IEnumerable(Of Type)  
                If type.IsInterface Then  
                    Dim types As New List(Of Type)()  
                    AddInterface(types, type)  
                    Return types  
                End If  
                Return SelfAndBaseClasses(type)  
            End Function  
     
            Private Shared Function SelfAndBaseClasses(ByVal type As Type) As IEnumerable(Of Type)  
                While type IsNot Nothing  
                    Return New Type() {type}  
                    typetype = type.BaseType  
                End While  
            End Function  
     
            Private Shared Sub AddInterface(ByVal types As List(Of Type), ByVal type As Type)  
                If Not types.Contains(type) Then  
                    types.Add(type)  
                    For Each t As Type In type.GetInterfaces()  
                        AddInterface(types, t)  
                    Next  
                End If  
            End Sub  
     
            Private Class MethodData  
                Public MethodBase As MethodBase  
                Public Parameters As ParameterInfo()  
                Public Args As Expression()  
            End Class  
     
            Private Function FindBestMethod(ByVal methods As IEnumerable(Of MethodBase), ByVal args As Expression(), ByVal method As MethodBase) As Integer  
                Dim applicable As MethodData() = methods.[Select](Function(m) New MethodData() With { _  
                  .MethodBase = m, _  
                  .Parameters = m.GetParameters() _  
                }).Where(Function(m) IsApplicable(m, args)).ToArray()  
                If applicable.Length > 1 Then  
                    applicableapplicable = applicable.Where(Function(m) applicable.All(Function(n) m.Equals(n) OrElse IsBetterThan(args, m, n))).ToArray()  
                End If  
                If applicable.Length = 1 Then  
                    Dim md As MethodData = applicable(0)  
                    For i As Integer = 0 To args.Length - 1  
                        args(i) = md.Args(i)  
                    Next  
                    method = md.MethodBase  
                Else  
                    method = Nothing 
                End If  
                Return applicable.Length  
            End Function  
     
            Private Function IsApplicable(ByVal method As MethodData, ByVal args As Expression()) As Boolean  
                If method.Parameters.Length <> args.Length Then  
                    Return False  
                End If  
                Dim promotedArgs As Expression() = New Expression(args.Length - 1) {}  
                For i As Integer = 0 To args.Length - 1  
                    Dim pi As ParameterInfo = method.Parameters(i)  
                    If pi.IsOut Then  
                        Return False  
                    End If  
                    Dim promoted As Expression = PromoteExpression(args(i), pi.ParameterType, False)  
                    If promoted Is Nothing Then  
                        Return False  
                    End If  
                    promotedArgs(i) = promoted  
                Next  
                method.Args = promotedArgs 
                Return True  
            End Function  
     
            Private Function PromoteExpression(ByVal expr As Expression, ByVal type__1 As Type, ByVal exact As Boolean) As Expression  
                If expr.Type.Equals(type__1) Then  
                    Return expr  
                End If  
                If TypeOf expr Is ConstantExpression Then  
                    Dim ce As ConstantExpression = DirectCast(expr, ConstantExpression)  
                    If ce.Equals(nullLiteral) Then  
                        If Not type__1.IsValueType OrElse IsNullableType(type__1) Then  
                            Return Expression.Constant(Nothing, type__1)  
                        End If  
                    Else  
                        Dim text As String  
                        If literals.TryGetValue(ce, text) Then  
                            Dim target As Type = GetNonNullableType(type__1)  
                            Dim value As [Object] = Nothing  
                            Select Case Type.GetTypeCode(ce.Type)  
                                Case TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64  
                                    value = ParseNumber(text, target)  
                                    Exit Select  
                                Case TypeCode.[Double]  
                                    If target Is GetType(Decimal) Then  
                                        value = ParseNumber(text, target)  
                                    End If  
                                    Exit Select  
                                Case TypeCode.[String]  
                                    value = ParseEnum(text, target)  
                                    Exit Select  
                            End Select  
                            If value IsNot Nothing Then  
                                Return Expression.Constant(value, type__1)  
                            End If  
                        End If  
                    End If  
                End If  
                If IsCompatibleWith(expr.Type, type__1) Then  
                    If type__1.IsValueType OrElse exact Then  
                        Return Expression.Convert(expr, type__1)  
                    End If  
                    Return expr  
                End If  
                Return Nothing  
            End Function  
     
            Private Shared Function ParseNumber(ByVal text As String, ByVal type__1 As Type) As Object  
                Select Case Type.GetTypeCode(GetNonNullableType(type__1))  
                    Case TypeCode.[SByte]  
                        Dim sb As SByte  
                        If SByte.TryParse(text, sb) Then  
                            Return sb  
                        End If  
                        Exit Select  
                    Case TypeCode.[Byte]  
                        Dim b As Byte  
                        If Byte.TryParse(text, b) Then  
                            Return b  
                        End If  
                        Exit Select  
                    Case TypeCode.Int16  
                        Dim s As Short  
                        If Short.TryParse(text, s) Then  
                            Return s  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt16  
                        Dim us As UShort  
                        If UShort.TryParse(text, us) Then  
                            Return us  
                        End If  
                        Exit Select  
                    Case TypeCode.Int32  
                        Dim i As Integer  
                        If Integer.TryParse(text, i) Then  
                            Return i  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt32  
                        Dim ui As UInteger  
                        If UInteger.TryParse(text, ui) Then  
                            Return ui  
                        End If  
                        Exit Select  
                    Case TypeCode.Int64  
                        Dim l As Long  
                        If Long.TryParse(text, l) Then  
                            Return l  
                        End If  
                        Exit Select  
                    Case TypeCode.UInt64  
                        Dim ul As ULong  
                        If ULong.TryParse(text, ul) Then  
                            Return ul  
                        End If  
                        Exit Select  
                    Case TypeCode.[Single]  
                        Dim f As Single  
                        If Single.TryParse(text, f) Then  
                            Return f  
                        End If  
                        Exit Select  
                    Case TypeCode.[Double]  
                        Dim d As Double  
                        If Double.TryParse(text, d) Then  
                            Return d  
                        End If  
                        Exit Select  
                    Case TypeCode.[Decimal]  
                        Dim e As Decimal  
                        If Decimal.TryParse(text, e) Then  
                            Return e  
                        End If  
                        Exit Select  
                End Select  
                Return Nothing  
            End Function  
     
            Private Shared Function ParseEnum(ByVal name As String, ByVal type__1 As Type) As Object  
                If type__1.IsEnum Then  
                    Dim memberInfos As MemberInfo() = type__1.FindMembers(MemberTypes.Field, BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or BindingFlags.[Static], Type.FilterNameIgnoreCase, name)  
                    If memberInfos.Length <> 0 Then  
                        Return DirectCast(memberInfos(0), FieldInfo).GetValue(Nothing)  
                    End If  
                End If  
                Return Nothing  
            End Function  
     
            Private Shared Function IsCompatibleWith(ByVal source As Type, ByVal target As Type) As Boolean  
                If source Is target Then  
                    Return True  
                End If  
                If Not target.IsValueType Then  
                    Return target.IsAssignableFrom(source)  
                End If  
                Dim st As Type = GetNonNullableType(source)  
                Dim tt As Type = GetNonNullableType(target)  
                If st IsNot source AndAlso tt Is target Then  
                    Return False  
                End If  
                Dim sc As TypeCode = If(st.IsEnum, TypeCode.[Object], Type.GetTypeCode(st))  
                Dim tc As TypeCode = If(tt.IsEnum, TypeCode.[Object], Type.GetTypeCode(tt))  
                Select Case sc  
                    Case TypeCode.[SByte]  
                        Select Case tc  
                            Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], _  
                             TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.[Byte]  
                        Select Case tc  
                            Case TypeCode.[Byte], TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, _  
                             TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int16  
                        Select Case tc  
                            Case TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt16  
                        Select Case tc  
                            Case TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.[Single], _  
                             TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int32  
                        Select Case tc  
                            Case TypeCode.Int32, TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt32  
                        Select Case tc  
                            Case TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.Int64  
                        Select Case tc  
                            Case TypeCode.Int64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.UInt64  
                        Select Case tc  
                            Case TypeCode.UInt64, TypeCode.[Single], TypeCode.[Double], TypeCode.[Decimal]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case TypeCode.[Single]  
                        Select Case tc  
                            Case TypeCode.[Single], TypeCode.[Double]  
                                Return True  
                        End Select  
                        Exit Select  
                    Case Else  
                        If st Is tt Then  
                            Return True  
                        End If  
                        Exit Select  
                End Select  
                Return False  
            End Function  
     
            Private Shared Function IsBetterThan(ByVal args As Expression(), ByVal m1 As MethodData, ByVal m2 As MethodData) As Boolean  
                Dim better As Boolean = False 
                For i As Integer = 0 To args.Length - 1  
                    Dim c As Integer = CompareConversions(args(i).Type, m1.Parameters(i).ParameterType, m2.Parameters(i).ParameterType)  
                    If c < 0 Then  
                        Return False  
                    End If  
                    If c > 0 Then  
                        better = True 
                    End If  
                Next  
                Return better  
            End Function  
     
            ' Return 1 if s -> t1 is a better conversion than s -> t2  
            ' Return -1 if s -> t2 is a better conversion than s -> t1  
            ' Return 0 if neither conversion is better  
            Private Shared Function CompareConversions(ByVal s As Type, ByVal t1 As Type, ByVal t2 As Type) As Integer  
                If t1 Is t2 Then  
                    Return 0  
                End If  
                If s Is t1 Then  
                    Return 1  
                End If  
                If s Is t2 Then  
                    Return -1  
                End If  
                Dim t1t2 As Boolean = IsCompatibleWith(t1, t2)  
                Dim t2t1 As Boolean = IsCompatibleWith(t2, t1)  
                If t1t2 AndAlso Not t2t1 Then  
                    Return 1  
                End If  
                If t2t1 AndAlso Not t1t2 Then  
                    Return -1  
                End If  
                If IsSignedIntegralType(t1) AndAlso IsUnsignedIntegralType(t2) Then  
                    Return 1  
                End If  
                If IsSignedIntegralType(t2) AndAlso IsUnsignedIntegralType(t1) Then  
                    Return -1  
                End If  
                Return 0  
            End Function  
     
            Private Function GenerateEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.Equal(left, right)  
            End Function  
     
            Private Function GenerateNotEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.NotEqual(left, right)  
            End Function  
     
            Private Function GenerateGreaterThan(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.GreaterThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.GreaterThan(left, right)  
            End Function  
     
            Private Function GenerateGreaterThanEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.GreaterThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.GreaterThanOrEqual(left, right)  
            End Function  
     
            Private Function GenerateLessThan(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.LessThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.LessThan(left, right)  
            End Function  
     
            Private Function GenerateLessThanEqual(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) Then  
                    Return Expression.LessThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0))  
                End If  
                Return Expression.LessThanOrEqual(left, right)  
            End Function  
     
            Private Function GenerateAdd(ByVal left As Expression, ByVal right As Expression) As Expression  
                If left.Type.Equals(GetType(String)) AndAlso right.Type.Equals(GetType(String)) Then  
                    Return GenerateStaticMethodCall("Concat", left, right)  
                End If  
                Return Expression.Add(left, right)  
            End Function  
     
            Private Function GenerateSubtract(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.Subtract(left, right)  
            End Function  
     
            Private Function GenerateStringConcat(ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.[Call](Nothing, GetType(String).GetMethod("Concat", New Object() {GetType(Object), GetType(Object)}), New Object() {left, right})  
            End Function  
     
            Private Function GetStaticMethod(ByVal methodName As String, ByVal left As Expression, ByVal right As Expression) As MethodInfo  
                Return left.Type.GetMethod(methodName, New Object() {left.Type, right.Type})  
            End Function  
     
            Private Function GenerateStaticMethodCall(ByVal methodName As String, ByVal left As Expression, ByVal right As Expression) As Expression  
                Return Expression.[Call](Nothing, GetStaticMethod(methodName, left, right), New Object() {left, right})  
            End Function  
     
            Private Sub SetTextPos(ByVal pos As Integer)  
                textPos = pos 
                ch = If(textPos < textLen, text(textPos), ControlChars.NullChar)  
            End Sub  
     
            Private Sub NextChar()  
                If textPos < textLen Then  
                    textPos += 1  
                End If  
                ch = If(textPos < textLen, text(textPos), ControlChars.NullChar)  
            End Sub  
     
            Private Sub NextToken()  
                While [Char].IsWhiteSpace(ch)  
                    NextChar()  
                End While  
                Dim t As TokenId  
                Dim tokenPos As Integer = textPos 
                Select Case ch  
                    Case "!"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.ExclamationEqual  
                        Else  
                            t = TokenId.Exclamation  
                        End If  
                        Exit Select  
                    Case "%"c  
                        NextChar()  
                        t = TokenId.Percent  
                        Exit Select  
                    Case "&"c  
                        NextChar()  
                        If cch = "&"c Then  
                            NextChar()  
                            t = TokenId.DoubleAmphersand  
                        Else  
                            t = TokenId.Amphersand  
                        End If  
                        Exit Select  
                    Case "("c  
                        NextChar()  
                        t = TokenId.OpenParen  
                        Exit Select  
                    Case ")"c  
                        NextChar()  
                        t = TokenId.CloseParen  
                        Exit Select  
                    Case "*"c  
                        NextChar()  
                        t = TokenId.Asterisk  
                        Exit Select  
                    Case "+"c  
                        NextChar()  
                        t = TokenId.Plus  
                        Exit Select  
                    Case ","c  
                        NextChar()  
                        t = TokenId.Comma  
                        Exit Select  
                    Case "-"c  
                        NextChar()  
                        t = TokenId.Minus  
                        Exit Select  
                    Case "."c  
                        NextChar()  
                        t = TokenId.Dot  
                        Exit Select  
                    Case "/"c  
                        NextChar()  
                        t = TokenId.Slash  
                        Exit Select  
                    Case ":"c  
                        NextChar()  
                        t = TokenId.Colon  
                        Exit Select  
                    Case "<"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.LessThanEqual  
                        ElseIf cch = ">"c Then  
                            NextChar()  
                            t = TokenId.LessGreater  
                        Else  
                            t = TokenId.LessThan  
                        End If  
                        Exit Select  
                    Case "="c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.DoubleEqual  
                        Else  
                            t = TokenId.Equal  
                        End If  
                        Exit Select  
                    Case ">"c  
                        NextChar()  
                        If cch = "="c Then  
                            NextChar()  
                            t = TokenId.GreaterThanEqual  
                        Else  
                            t = TokenId.GreaterThan  
                        End If  
                        Exit Select  
                    Case "?"c  
                        NextChar()  
                        t = TokenId.Question  
                        Exit Select  
                    Case "["c  
                        NextChar()  
                        t = TokenId.OpenBracket  
                        Exit Select  
                    Case "]"c  
                        NextChar()  
                        t = TokenId.CloseBracket  
                        Exit Select  
                    Case "|"c  
                        NextChar()  
                        If cch = "|"c Then  
                            NextChar()  
                            t = TokenId.DoubleBar  
                        Else  
                            t = TokenId.Bar  
                        End If  
                        Exit Select  
                    Case """"c, "'"c  
                        Dim quote As Char = ch 
                        Do  
                            NextChar()  
                            While textPos < textLen AndAlso ch <> quote  
                                NextChar()  
                            End While  
                            If textPos = textLen Then  
                                Throw ParseError(textPos, Res.UnterminatedStringLiteral)  
                            End If  
                            NextChar()  
                        Loop While ch = quote 
                        t = TokenId.StringLiteral  
                        Exit Select  
                    Case Else  
                        If [Char].IsLetter(ch) OrElse cch = "@"c OrElse cch = "_"c Then  
                            Do  
                                NextChar()  
                            Loop While [Char].IsLetterOrDigit(ch) OrElse cch = "_"c  
                            t = TokenId.Identifier  
                            Exit Select  
                        End If  
                        If [Char].IsDigit(ch) Then  
                            t = TokenId.IntegerLiteral  
                            Do  
                                NextChar()  
                            Loop While [Char].IsDigit(ch)  
                            If cch = "."c Then  
                                t = TokenId.RealLiteral  
                                NextChar()  
                                ValidateDigit()  
                                Do  
                                    NextChar()  
                                Loop While [Char].IsDigit(ch)  
                            End If  
                            If cch = "E"c OrElse cch = "e"c Then  
                                t = TokenId.RealLiteral  
                                NextChar()  
                                If cch = "+"c OrElse cch = "-"c Then  
                                    NextChar()  
                                End If  
                                ValidateDigit()  
                                Do  
                                    NextChar()  
                                Loop While [Char].IsDigit(ch)  
                            End If  
                            If cch = "F"c OrElse cch = "f"c Then  
                                NextChar()  
                            End If  
                            Exit Select  
                        End If  
                        If textPos = textLen Then  
                            t = TokenId.[End]  
                            Exit Select  
                        End If  
                        Throw ParseError(textPos, Res.InvalidCharacter, ch)  
                End Select  
                varToken.id = t 
                varToken.text = text.Substring(tokenPos, textPos - tokenPos)  
                varToken.pos = tokenPos 
            End Sub  
     
            Private Function TokenIdentifierIs(ByVal id As String) As Boolean  
                Return varToken.id = TokenId.Identifier AndAlso [String].Equals(id, varToken.text, StringComparison.OrdinalIgnoreCase)  
            End Function  
     
            Private Function GetIdentifier() As String  
                ValidateToken(TokenId.Identifier, Res.IdentifierExpected)  
                Dim id As String = varToken.text  
                If id.Length > 1 AndAlso id(0) = "@"c Then  
                    idid = id.Substring(1)  
                End If  
                Return id  
            End Function  
     
            Private Sub ValidateDigit()  
                If Not [Char].IsDigit(ch) Then  
                    Throw ParseError(textPos, Res.DigitExpected)  
                End If  
            End Sub  
     
            Private Sub ValidateToken(ByVal t As TokenId, ByVal errorMessage As String)  
                If varToken.id <> t Then  
                    Throw ParseError(errorMessage)  
                End If  
            End Sub  
     
            Private Sub ValidateToken(ByVal t As TokenId)  
                If varToken.id <> t Then  
                    Throw ParseError(Res.SyntaxError)  
                End If  
            End Sub  
     
            Private Function ParseError(ByVal format As String, ByVal ParamArray args As Object()) As Exception  
                Return ParseError(varToken.pos, format, args)  
            End Function  
     
            Private Function ParseError(ByVal pos As Integer, ByVal format As String, ByVal ParamArray args As Object()) As Exception  
                Return New ParseException(String.Format(Globalization.CultureInfo.CurrentCulture, format, args), pos)  
            End Function  
     
            Private Shared Function CreateKeywords() As Dictionary(Of String, Object)  
                Dim d As New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)  
                d.Add("true", trueLiteral)  
                d.Add("false", falseLiteral)  
                d.Add("null", nullLiteral)  
                d.Add(keywordIt, keywordIt)  
                d.Add(keywordIif, keywordIif)  
                d.Add(keywordNew, keywordNew)  
                For Each type As Type In predefinedTypes  
                    d.Add(type.Name, type)  
                Next  
                Return d  
            End Function  
            Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T  
                target = value 
                Return value  
            End Function  
        End Class  
     
        NotInheritable Class Res  
            Private Sub New()  
            End Sub  
            Public Const DuplicateIdentifier As String = "The identifier '{0}' was defined more than once" 
            Public Const ExpressionTypeMismatch As String = "Expression of type '{0}' expected" 
            Public Const ExpressionExpected As String = "Expression expected" 
            Public Const InvalidCharacterLiteral As String = "Character literal must contain exactly one character" 
            Public Const InvalidIntegerLiteral As String = "Invalid integer literal '{0}'" 
            Public Const InvalidRealLiteral As String = "Invalid real literal '{0}'" 
            Public Const UnknownIdentifier As String = "Unknown identifier '{0}'" 
            Public Const NoItInScope As String = "No 'it' is in scope" 
            Public Const IifRequiresThreeArgs As String = "The 'iif' function requires three arguments" 
            Public Const FirstExprMustBeBool As String = "The first expression must be of type 'Boolean'" 
            Public Const BothTypesConvertToOther As String = "Both of the types '{0}' and '{1}' convert to the other" 
            Public Const NeitherTypeConvertsToOther As String = "Neither of the types '{0}' and '{1}' converts to the other" 
            Public Const MissingAsClause As String = "Expression is missing an 'as' clause" 
            Public Const ArgsIncompatibleWithLambda As String = "Argument list incompatible with lambda expression" 
            Public Const TypeHasNoNullableForm As String = "Type '{0}' has no nullable form" 
            Public Const NoMatchingConstructor As String = "No matching constructor in type '{0}'" 
            Public Const AmbiguousConstructorInvocation As String = "Ambiguous invocation of '{0}' constructor" 
            Public Const CannotConvertValue As String = "A value of type '{0}' cannot be converted to type '{1}'" 
            Public Const NoApplicableMethod As String = "No applicable method '{0}' exists in type '{1}'" 
            Public Const MethodsAreInaccessible As String = "Methods on type '{0}' are not accessible" 
            Public Const MethodIsVoid As String = "Method '{0}' in type '{1}' does not return a value" 
            Public Const AmbiguousMethodInvocation As String = "Ambiguous invocation of method '{0}' in type '{1}'" 
            Public Const UnknownPropertyOrField As String = "No property or field '{0}' exists in type '{1}'" 
            Public Const NoApplicableAggregate As String = "No applicable aggregate method '{0}' exists" 
            Public Const CannotIndexMultiDimArray As String = "Indexing of multi-dimensional arrays is not supported" 
            Public Const InvalidIndex As String = "Array index must be an integer expression" 
            Public Const NoApplicableIndexer As String = "No applicable indexer exists in type '{0}'" 
            Public Const AmbiguousIndexerInvocation As String = "Ambiguous invocation of indexer in type '{0}'" 
            Public Const IncompatibleOperand As String = "Operator '{0}' incompatible with operand type '{1}'" 
            Public Const IncompatibleOperands As String = "Operator '{0}' incompatible with operand types '{1}' and '{2}'" 
            Public Const UnterminatedStringLiteral As String = "Unterminated string literal" 
            Public Const InvalidCharacter As String = "Syntax error '{0}'" 
            Public Const DigitExpected As String = "Digit expected" 
            Public Const SyntaxError As String = "Syntax error" 
            Public Const TokenExpected As String = "{0} expected" 
            Public Const ParseExceptionFormat As String = "{0} (at index {1})" 
            Public Const ColonExpected As String = "':' expected" 
            Public Const OpenParenExpected As String = "'(' expected" 
            Public Const CloseParenOrOperatorExpected As String = "')' or operator expected" 
            Public Const CloseParenOrCommaExpected As String = "')' or ',' expected" 
            Public Const DotOrOpenParenExpected As String = "'.' or '(' expected" 
            Public Const OpenBracketExpected As String = "'[' expected" 
            Public Const CloseBracketOrCommaExpected As String = "']' or ',' expected" 
            Public Const IdentifierExpected As String = "Identifier expected" 
        End Class  
    End Namespace 

  • FunnyNjK 08 Dec 2010
    Hello,

    I have been searching for two days for a solotion to bind a SilverLight DataGrid to a DataTable or DataSet, and I finally found the solution here.

    Works perfectly!

    Thank you so much!

    Another great reason why Telerik Developers Rock!  I should have looked here in the first place.
  • Fabio 25 Dec 2010
    Hi Friends !

    I'm having some problem here:
    Error 2 Argument 1: cannot convert from 'classDataStore.linkdoctorService.ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType[][]' to 'System.Collections.Generic.IEnumerable<System.Collections.Generic.Dictionary<string,object>>' P:\projetos\linkdoctor\classDataStore\classDataStore.cs 101 30 classDataStore

    In this line:

    var ldService = new linkdoctorService.linkdoctorWebServiceClient();
                ldService.getDataCompleted += (s, e) =>
                {
                    getResultSet(e.Result); <-- error here !!!
                };
    ...

    Here is my webservice contract:



            [OperationContract]  
            public System.Collections.Generic.IEnumerable<System.Collections.Generic.Dictionary<stringobject>> getData(DataTable resultSet)  
            {  
                var table = resultSet;  
     
                var columns = table.Columns.Cast<DataColumn>();  
     
                return table.AsEnumerable().Select(r => columns.Select(c =>  
                                     new { Column = c.ColumnName, Value = r[c] })  
                                 .ToDictionary(i => i.Column, i => i.Value != DBNull.Value ? i.Value : null));  
            } 



    What's wrong ?

    Best regards


  • Sam 14 Jan 2011
    Vlad,

    I have a question for you.  Is there a simple way to add new rows to the grid using this?  I am trying to retrieve data in chunks from a database, and instead of returning everything all the time, I only want to return new rows and add those rows to the gridview.  I have been struggling with trying to convert stuff around to add items, etc.  If I create a local datatable variable from the itemssource, and add the new rows to it, it appears to do nothing....so, I am wondering how you would go about appending rows?

    Thanks.
    Sam
  • Mark Davison 27 Jan 2011
    Hi.

    Can anyone tell me if it is possible to implement INotifyPropertyChanged on this so that the bound grid will automatically reflect any changes to the dataset?

    Not even sure if this is possible with this implementation.

    Regards,

    Mark
  • Mark Davison 27 Jan 2011
    Hi.

    Can anyone tell me if it is possible to implement INotifyPropertyChanged on this so that the bound grid will automatically reflect any changes to the dataset?

    Not even sure if this is possible with this implementation.

    Regards,

    Mark
  • Armin 10 Feb 2011
    Hello
    thanks a lot for your comments
    i have a problem with WCF Ria Service
    how can i use your project with WCF Ria Service and Silverlight 4.0 and Domain Service
    thank you for attention
    Bye
  • Armin 10 Feb 2011
    Hello
    thanks a lot for your comments
    i have a problem with WCF Ria Service
    how can i use your project with WCF Ria Service and Silverlight 4.0 and Domain Service
    thank you for attention
    Bye
  • SIRO 17 Mar 2011
    Hello Vladimir, I have been looking at this code and I'm really interested in it, but could you give me any idea about using it with an editable radgridview control please?
  • Ron Larvick 02 Apr 2011
    How would you reverse this to save changes back to the datasource?
  • MENG 22 May 2011
    Hi.

    Can anyone tell me if it is possible to implement INotifyPropertyChanged on this so that the bound grid will automatically reflect any changes to the dataset?

    Not even sure if this is possible with this implementation.

    Regards,

  • Timur 17 Sep 2011
    Hi Vlad!
    Thanks for the post, it is really cool!
    But it is still not a direct link to the dataset, is it? I mean, is it possible for your RadGridView to take only the records it displays and if i scroll down then it loads more data and displays it? Like a load-on-demand? 
    Any answer would be highly appreciated! I am really stuck on this!

Add comment

  1. Formatting options
       
     
     
     
     
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)