activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject [38/50] [abbrv] activemq-nms-msmq git commit: Apply patch for AMQNET-554. Suport for message properties, and selectors. Thanks Stephane Ramet!
Date Tue, 07 Mar 2017 19:39:18 GMT
http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Readers/MessageReaderUtil.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Readers/MessageReaderUtil.cs b/src/main/csharp/Readers/MessageReaderUtil.cs
new file mode 100644
index 0000000..c303965
--- /dev/null
+++ b/src/main/csharp/Readers/MessageReaderUtil.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Messaging;
+using System.Globalization;
+using System.Text.RegularExpressions;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.MSMQ.Readers
+{
+    /// <summary>
+    /// Utility routines for creating MSMQ message readers.
+    /// </summary>
+	public static class MessageReaderUtil
+	{
+        private static Regex basicSelectorRegex =
+            new Regex(@"^\s*" +
+                      @"(NMSMessageId)\s*=\s*'([^']*)'|" +
+                      @"(NMSCorrelationId)\s*=\s*'([^']*)'|" +
+                      @"(LookupId)\s*=\s*([-+]{0,1}\d+)" +
+                      @"\s*$",
+                RegexOptions.IgnoreCase | RegexOptions.Compiled);
+
+        /// <summary>
+        /// Creates a message reader for the specified message selector.
+        /// </summary>
+        /// <param name="messageQueue">The MSMQ message queue from which
+        /// messages will be read.</param>
+        /// <param name="messageConverter">A message converter for mapping
+        /// MSMQ messages to NMS messages.</param>
+        /// <param name="selector">The message selector.</param>
+        /// <return>A reader for the specified selector.</return>
+        public static IMessageReader CreateMessageReader(
+            MessageQueue messageQueue, IMessageConverter messageConverter,
+            string selector)
+        {
+            IMessageReader reader;
+
+            if(string.IsNullOrEmpty(selector))
+            {
+                reader = new NonFilteringMessageReader(messageQueue,
+                    messageConverter);
+            }
+            else
+            {
+                Match match = basicSelectorRegex.Match(selector);
+                if(match.Success)
+                {
+                    if(!string.IsNullOrEmpty(match.Groups[1].Value))
+                    {
+                        reader = new ByIdMessageReader(messageQueue,
+                            messageConverter, match.Groups[2].Value);
+                    }
+                    else if(!string.IsNullOrEmpty(match.Groups[3].Value))
+                    {
+                        reader = new ByCorrelationIdMessageReader(messageQueue,
+                            messageConverter, match.Groups[4].Value);
+                    }
+                    else
+                    {
+                        Int64 lookupId = Int64.Parse(match.Groups[6].Value,
+                            CultureInfo.InvariantCulture);
+
+                        reader = new ByLookupIdMessageReader(messageQueue,
+                            messageConverter, lookupId);
+                    }
+                }
+                else
+                {
+                    reader = new BySelectorMessageReader(messageQueue,
+                        messageConverter, selector);
+                }
+            }
+
+            return reader;
+        }
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Readers/NonFilteringMessageReader.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Readers/NonFilteringMessageReader.cs b/src/main/csharp/Readers/NonFilteringMessageReader.cs
new file mode 100644
index 0000000..ea98baf
--- /dev/null
+++ b/src/main/csharp/Readers/NonFilteringMessageReader.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Messaging;
+using Apache.NMS.MSMQ;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.MSMQ.Readers
+{
+    /// <summary>
+    /// MSMQ message reader, returning all messages, without filtering.
+    /// </summary>
+	public class NonFilteringMessageReader : AbstractMessageReader
+	{
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="messageQueue">The MSMQ message queue from which
+        /// messages will be read.</param>
+        /// <param name="messageConverter">A message converter for mapping
+        /// MSMQ messages to NMS messages.</param>
+        public NonFilteringMessageReader(MessageQueue messageQueue,
+            IMessageConverter messageConverter)
+            : base(messageQueue, messageConverter)
+        {
+        }
+
+        /// <summary>
+        /// Returns without removing (peeks) the first message in the queue
+        /// referenced by this MessageQueue matching the selection criteria.
+        /// The Peek method is synchronous, so it blocks the current thread
+        /// until a message becomes available.
+        /// </summary>
+        /// <returns>Peeked message.</returns>
+        public override IMessage Peek()
+        {
+            return Convert(messageQueue.Peek());
+        }
+
+        /// <summary>
+        /// Returns without removing (peeks) the first message in the queue
+        /// referenced by this MessageQueue matching the selection criteria.
+        /// The Peek method is synchronous, so it blocks the current thread
+        /// until a message becomes available or the specified time-out occurs.
+        /// </summary>
+        /// <param name="timeSpan">Reception time-out.</param>
+        /// <returns>Peeked message.</returns>
+        public override IMessage Peek(TimeSpan timeSpan)
+        {
+            return Convert(messageQueue.Peek(timeSpan));
+        }
+
+        /// <summary>
+        /// Receives the first message available in the queue referenced by
+        /// the MessageQueue matching the selection criteria.
+        /// This call is synchronous, and blocks the current thread of execution
+        /// until a message is available.
+        /// </summary>
+        /// <returns>Received message.</returns>
+        public override IMessage Receive()
+        {
+            return Convert(messageQueue.Receive());
+        }
+
+        /// <summary>
+        /// Receives the first message available in the queue referenced by the
+        /// MessageQueue matching the selection criteria, and waits until either
+        /// a message is available in the queue, or the time-out expires.
+        /// </summary>
+        /// <param name="timeSpan">Reception time-out.</param>
+        /// <returns>Received message.</returns>
+        public override IMessage Receive(TimeSpan timeSpan)
+        {
+            return Convert(messageQueue.Receive(timeSpan));
+        }
+
+        /// <summary>
+        /// Receives the first message available in the transactional queue
+        /// referenced by the MessageQueue matching the selection criteria.
+        /// This call is synchronous, and blocks the current thread of execution
+        /// until a message is available.
+        /// </summary>
+        /// <param name="transaction">Transaction.</param>
+        /// <returns>Received message.</returns>
+        public override IMessage Receive(MessageQueueTransaction transaction)
+        {
+            return Convert(messageQueue.Receive(transaction));
+        }
+
+        /// <summary>
+        /// Receives the first message available in the transactional queue
+        /// referenced by the MessageQueue matching the selection criteria,
+        /// and waits until either a message is available in the queue, or the
+        /// time-out expires.
+        /// </summary>
+        /// <param name="timeSpan">Reception time-out.</param>
+        /// <param name="transaction">Transaction.</param>
+        /// <returns>Received message.</returns>
+        public override IMessage Receive(TimeSpan timeSpan,
+            MessageQueueTransaction transaction)
+        {
+            return Convert(messageQueue.Receive(timeSpan, transaction));
+        }
+
+        /// <summary>
+        /// Checks if an MSMQ message matches the selection criteria.
+        /// </summary>
+        /// <param name="message">MSMQ message.</param>
+        /// <return>true if the message matches the selection criteria.</return>
+        public override bool Matches(Message message)
+        {
+            return true;
+        }
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/ANDExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/ANDExpression.cs b/src/main/csharp/Selector/ANDExpression.cs
new file mode 100644
index 0000000..285efe3
--- /dev/null
+++ b/src/main/csharp/Selector/ANDExpression.cs
@@ -0,0 +1,47 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a logical AND combination of two expressions.
+    /// </summary>
+    public class ANDExpression : LogicExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return "AND"; }
+        }
+
+        public ANDExpression(IBooleanExpression left, IBooleanExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object lvalue = Left.Evaluate(message);
+            if(lvalue == null) return null;
+            if(!(bool)lvalue) return false;
+
+            object rvalue = Right.Evaluate(message);
+            return rvalue == null ? null : rvalue;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/AlignedNumericValues.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/AlignedNumericValues.cs b/src/main/csharp/Selector/AlignedNumericValues.cs
new file mode 100644
index 0000000..96e2eeb
--- /dev/null
+++ b/src/main/csharp/Selector/AlignedNumericValues.cs
@@ -0,0 +1,175 @@
+using System;
+using System.Globalization;
+using System.Collections.Generic;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A couple of numeric values converted to the type of the largest type.
+    /// </summary>
+    public class AlignedNumericValues
+    {
+        private object left;
+        public object Left
+        {
+            get { return left; }
+        }
+
+        private object right;
+        public object Right
+        {
+            get { return right; }
+        }
+
+        private T type;
+        public T TypeEnum
+        {
+            get { return type; }
+        }
+
+        public Type Type
+        {
+            get { return GetType(type); }
+        }
+
+        public AlignedNumericValues(object lvalue, object rvalue)
+        {
+            if(lvalue == null || rvalue == null)
+            {
+                return;
+            }
+
+            T ltypeEnum = GetTypeEnum(lvalue);
+            T rtypeEnum = GetTypeEnum(rvalue);
+
+            type = targetType[(int)ltypeEnum][(int)rtypeEnum];
+
+            left  = (ltypeEnum == type ? lvalue : ConvertValue(lvalue, type));
+            right = (rtypeEnum == type ? rvalue : ConvertValue(rvalue, type));
+        }
+
+        public enum T
+        {
+            SByteType  =  0, // Signed 8-bit integer (-128 to 127)
+            ByteType   =  1, // Unsigned 8-bit integer (0 to 255)
+            CharType   =  2, // Unicode 16-bit character (U+0000 to U+ffff)
+            ShortType  =  3, // Signed 16-bit integer (-32 768 to 32 767)
+            UShortType =  4, // Unsigned 16-bit integer (0 to 65 535)
+            IntType    =  5, // Signed 32-bit integer (-2 147 483 648 to 2 147 483 647)
+            UIntType   =  6, // Unsigned 32-bit integer (0 to 4 294 967 295)
+            LongType   =  7, // Signed 64-bit integer (-9 223 372 036 854 775 808 to 9 223 372 036 854 775 807)
+            ULongType  =  8, // Unsigned 64-bit integer (0 to 18 446 744 073 709 551 615)
+            FloatType  =  9, // 7 digits (±1.5e−45 to ±3.4e38)
+            DoubleType = 10  // 15-16 digits (±5.0e−324 to ±1.7e308)
+        }
+
+        private static Dictionary<Type, T> typeEnums
+            = new Dictionary<Type, T>
+                {
+                    { typeof(sbyte ), T.SByteType  },
+                    { typeof(byte  ), T.ByteType   },
+                    { typeof(char  ), T.CharType   },
+                    { typeof(short ), T.ShortType  },
+                    { typeof(ushort), T.UShortType },
+                    { typeof(int   ), T.IntType    },
+                    { typeof(uint  ), T.UIntType   },
+                    { typeof(long  ), T.LongType   },
+                    { typeof(ulong ), T.ULongType  },
+                    { typeof(float ), T.FloatType  },
+                    { typeof(double), T.DoubleType }
+                };
+
+        private static T[][] targetType = new T[][]
+        {
+            //                        SByteType ,   ByteType  ,   CharType  ,   ShortType ,   UShortType,   IntType   ,   UIntType  ,   LongType  ,   ULongType ,   FloatType ,   DoubleType
+            /*SByteType */new T[] { T.SByteType , T.ShortType , T.IntType   , T.ShortType , T.IntType   , T.IntType   , T.LongType  , T.LongType  , T.LongType  , T.FloatType , T.DoubleType },
+            /*ByteType  */new T[] { T.ShortType , T.ByteType  , T.UShortType, T.ShortType , T.UShortType, T.IntType   , T.UIntType  , T.LongType  , T.ULongType , T.FloatType , T.DoubleType },
+            /*CharType  */new T[] { T.IntType   , T.UShortType, T.CharType  , T.IntType   , T.UShortType, T.IntType   , T.LongType  , T.LongType  , T.ULongType , T.FloatType , T.DoubleType },
+            /*ShortType */new T[] { T.ShortType , T.ShortType , T.IntType   , T.ShortType , T.IntType   , T.IntType   , T.LongType  , T.LongType  , T.LongType  , T.FloatType , T.DoubleType },
+            /*UShortType*/new T[] { T.IntType   , T.UShortType, T.UShortType, T.IntType   , T.UShortType, T.IntType   , T.UIntType  , T.LongType  , T.ULongType , T.FloatType , T.DoubleType },
+            /*IntType   */new T[] { T.IntType   , T.IntType   , T.IntType   , T.IntType   , T.IntType   , T.IntType   , T.LongType  , T.LongType  , T.LongType  , T.FloatType , T.DoubleType },
+            /*UIntType  */new T[] { T.LongType  , T.UIntType  , T.LongType  , T.LongType  , T.UIntType  , T.LongType  , T.UIntType  , T.LongType  , T.ULongType , T.FloatType , T.DoubleType },
+            /*LongType  */new T[] { T.LongType  , T.LongType  , T.LongType  , T.LongType  , T.LongType  , T.LongType  , T.LongType  , T.LongType  , T.LongType  , T.FloatType , T.DoubleType },
+            /*ULongType */new T[] { T.LongType  , T.ULongType , T.ULongType , T.LongType  , T.ULongType , T.LongType  , T.ULongType , T.LongType  , T.ULongType , T.FloatType , T.DoubleType },
+            /*FloatType */new T[] { T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.DoubleType },
+            /*DoubleType*/new T[] { T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType }
+        };
+
+        private T GetTypeEnum(object value)
+        {
+            return GetTypeEnum(value.GetType());
+        }
+
+        private T GetTypeEnum(Type type)
+        {
+            try
+            {
+                return typeEnums[type];
+            }
+            catch
+            {
+                throw new NotSupportedException(
+                    string.Format("Unsupported data type {0}.", type));
+            }
+        }
+
+        private Type GetType(T typeEnum)
+        {
+            switch(typeEnum)
+            {
+                case T.SByteType : return typeof(sbyte );
+                case T.ByteType  : return typeof(byte  );
+                case T.CharType  : return typeof(char  );
+                case T.ShortType : return typeof(short );
+                case T.UShortType: return typeof(ushort);
+                case T.IntType   : return typeof(int   );
+                case T.UIntType  : return typeof(uint  );
+                case T.LongType  : return typeof(long  );
+                case T.ULongType : return typeof(ulong );
+                case T.FloatType : return typeof(float );
+                case T.DoubleType: return typeof(double);
+                default:
+                    throw new NotSupportedException(
+                        string.Format("Unsupported data type {0}.", typeEnum));
+            }
+        }
+
+        private object ConvertValue(object value, T targetTypeEnum)
+        {
+            switch(targetTypeEnum)
+            {
+                case T.SByteType : return Convert.ToSByte (value);
+                case T.ByteType  : return Convert.ToByte  (value);
+                case T.CharType  : return Convert.ToChar  (value);
+                case T.ShortType : return Convert.ToInt16 (value);
+                case T.UShortType: return Convert.ToUInt16(value);
+                case T.IntType   : return Convert.ToInt32 (value);
+                case T.UIntType  : return Convert.ToUInt32(value);
+                case T.LongType  : return Convert.ToInt64 (value);
+                case T.ULongType : return Convert.ToUInt64(value);
+                case T.FloatType : return Convert.ToSingle(value);
+                case T.DoubleType: return Convert.ToDouble(value);
+                default:
+                    throw new NotSupportedException(
+                        string.Format("Unsupported data type {0}.", targetTypeEnum));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/ArithmeticExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/ArithmeticExpression.cs b/src/main/csharp/Selector/ArithmeticExpression.cs
new file mode 100644
index 0000000..a0524ee
--- /dev/null
+++ b/src/main/csharp/Selector/ArithmeticExpression.cs
@@ -0,0 +1,57 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// An expression which performs an operation on two expression values.
+    /// </summary>
+    public abstract class ArithmeticExpression : BinaryExpression
+    {
+        public ArithmeticExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public static IExpression CreatePlus(IExpression left, IExpression right)
+        {
+            return new PlusExpression(left, right);
+        }
+
+        public static IExpression CreateMinus(IExpression left, IExpression right)
+        {
+            return new MinusExpression(left, right);
+        }
+
+        public static IExpression CreateMultiply(IExpression left, IExpression right)
+        {
+            return new MultiplyExpression(left, right);
+        }
+
+        public static IExpression CreateDivide(IExpression left, IExpression right)
+        {
+            return new DivideExpression(left, right);
+        }
+
+        public static IExpression CreateMod(IExpression left, IExpression right)
+        {
+            return new ModExpression(left, right);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/BinaryExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/BinaryExpression.cs b/src/main/csharp/Selector/BinaryExpression.cs
new file mode 100644
index 0000000..9206f8c
--- /dev/null
+++ b/src/main/csharp/Selector/BinaryExpression.cs
@@ -0,0 +1,59 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// An expression which performs an operation on two expression values.
+    /// </summary>
+    public abstract class BinaryExpression : IExpression
+    {
+        protected IExpression leftExpression;
+        public IExpression Left
+        {
+            get { return leftExpression; }
+            set { leftExpression = value; }
+        }
+
+        protected IExpression rightExpression;
+        public IExpression Right
+        {
+            get { return rightExpression; }
+            set { rightExpression = value; }
+        }
+
+        protected abstract string ExpressionSymbol
+        {
+            get;
+        }
+
+        public BinaryExpression(IExpression left, IExpression right)
+        {
+            leftExpression = left;
+            rightExpression = right;
+        }
+
+        public abstract object Evaluate(MessageEvaluationContext message);
+
+        public override string ToString()
+        {
+            return "(" + leftExpression.ToString() + " " + ExpressionSymbol + " " + rightExpression.ToString() + ")";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/BooleanCastExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/BooleanCastExpression.cs b/src/main/csharp/Selector/BooleanCastExpression.cs
new file mode 100644
index 0000000..26a6e9e
--- /dev/null
+++ b/src/main/csharp/Selector/BooleanCastExpression.cs
@@ -0,0 +1,45 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// An expression which casts an expression value to a boolean.
+    /// </summary>
+    public class BooleanCastExpression : BooleanUnaryExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return ""; }
+        }
+
+        public BooleanCastExpression(IExpression left)
+            : base(left)
+        {
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object rvalue = Right.Evaluate(message);
+            if(rvalue == null   ) return null;
+            if(rvalue is bool   ) return (bool)rvalue;
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/BooleanConstantExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/BooleanConstantExpression.cs b/src/main/csharp/Selector/BooleanConstantExpression.cs
new file mode 100644
index 0000000..eb6447a
--- /dev/null
+++ b/src/main/csharp/Selector/BooleanConstantExpression.cs
@@ -0,0 +1,38 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// Represents a boolean constant expression.
+    /// </summary>
+    public class BooleanConstantExpression : ConstantExpression, IBooleanExpression
+    {
+        public BooleanConstantExpression(object value)
+            : base(value)
+        {
+        }
+
+        public bool Matches(MessageEvaluationContext message)
+        {
+            object value = Evaluate(message);
+            return value != null && (bool)value;            
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/BooleanUnaryExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/BooleanUnaryExpression.cs b/src/main/csharp/Selector/BooleanUnaryExpression.cs
new file mode 100644
index 0000000..3873050
--- /dev/null
+++ b/src/main/csharp/Selector/BooleanUnaryExpression.cs
@@ -0,0 +1,39 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// An expression which performs an operation on one expression value
+    /// and returns a boolean value.
+    /// </summary>
+    public abstract class BooleanUnaryExpression : UnaryExpression, IBooleanExpression
+    {
+        public BooleanUnaryExpression(IExpression left)
+            : base(left)
+        {        	
+        }
+
+        public bool Matches(MessageEvaluationContext message)
+        {
+            object value = Evaluate(message);
+            return value != null && (bool)value;            
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/ComparisonExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/ComparisonExpression.cs b/src/main/csharp/Selector/ComparisonExpression.cs
new file mode 100644
index 0000000..4024271
--- /dev/null
+++ b/src/main/csharp/Selector/ComparisonExpression.cs
@@ -0,0 +1,162 @@
+using System;
+using System.Collections;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a comparison of two or more expressions or objects.
+    /// </summary>
+    public abstract class ComparisonExpression : BinaryExpression, IBooleanExpression
+    {
+        public ComparisonExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object lvalue = Left.Evaluate(message);
+            object rvalue = Right.Evaluate(message);
+
+            int? compared = null;
+
+            if(lvalue == null || rvalue == null)
+            {
+                if(lvalue == null && rvalue == null)
+                {
+                    compared = 0;
+                }
+            }
+            else
+            {
+                if(lvalue == rvalue)
+                {
+                    compared = 0;
+                }
+                else if(lvalue is string && rvalue is string)
+                {
+                    compared = ((string)lvalue).CompareTo(rvalue);
+                }
+                else
+                {
+                    AlignedNumericValues values = new AlignedNumericValues(lvalue, rvalue);
+
+                    switch(values.TypeEnum)
+                    {
+                        case AlignedNumericValues.T.SByteType : compared = ((sbyte )values.Left).CompareTo((sbyte )values.Right); break;
+                        case AlignedNumericValues.T.ByteType  : compared = ((byte  )values.Left).CompareTo((byte  )values.Right); break;
+                        case AlignedNumericValues.T.CharType  : compared = ((char  )values.Left).CompareTo((char  )values.Right); break;
+                        case AlignedNumericValues.T.ShortType : compared = ((short )values.Left).CompareTo((short )values.Right); break;
+                        case AlignedNumericValues.T.UShortType: compared = ((ushort)values.Left).CompareTo((ushort)values.Right); break;
+                        case AlignedNumericValues.T.IntType   : compared = ((int   )values.Left).CompareTo((int   )values.Right); break;
+                        case AlignedNumericValues.T.UIntType  : compared = ((uint  )values.Left).CompareTo((uint  )values.Right); break;
+                        case AlignedNumericValues.T.LongType  : compared = ((long  )values.Left).CompareTo((long  )values.Right); break;
+                        case AlignedNumericValues.T.ULongType : compared = ((ulong )values.Left).CompareTo((ulong )values.Right); break;
+                        case AlignedNumericValues.T.FloatType : compared = ((float )values.Left).CompareTo((float )values.Right); break;
+                        case AlignedNumericValues.T.DoubleType: compared = ((double)values.Left).CompareTo((double)values.Right); break;
+                    }
+                }
+            }
+
+            return AsBoolean(compared);
+        }
+    
+        public abstract bool AsBoolean(int? compared);
+
+        public bool Matches(MessageEvaluationContext message)
+        {
+            object value = Evaluate(message);
+            return value != null && (bool)value;            
+        }
+
+        // Equality expressions
+        public static IBooleanExpression CreateEqual(IExpression left, IExpression right)
+        {
+    	    return new EqualExpression(left, right, true);
+        }
+
+        public static IBooleanExpression CreateNotEqual(IExpression left, IExpression right)
+        {
+            return new EqualExpression(left, right, false);
+        }
+
+        public static IBooleanExpression CreateIsNull(IExpression left)
+        {
+            return new IsNullExpression(left, true);
+        }
+
+        public static IBooleanExpression CreateIsNotNull(IExpression left)
+        {
+            return new IsNullExpression(left, false);
+        }
+
+        // Binary comparison expressions
+        public static IBooleanExpression CreateGreaterThan(IExpression left, IExpression right)
+        {
+    	    return new GreaterExpression(left, right);
+        }
+
+        public static IBooleanExpression CreateGreaterThanOrEqual(IExpression left, IExpression right)
+        {
+    	    return new GreaterOrEqualExpression(left, right);
+        }
+
+        public static IBooleanExpression CreateLesserThan(IExpression left, IExpression right)
+        {
+    	    return new LesserExpression(left, right);
+        }
+
+	    public static IBooleanExpression CreateLesserThanOrEqual(IExpression left, IExpression right)
+        {
+    	    return new LesserOrEqualExpression(left, right);
+        }
+
+        // Other comparison expressions
+        public static IBooleanExpression CreateLike(IExpression left, string right, string escape)
+        {
+            return new LikeExpression(left, right, escape, true);
+        }
+
+        public static IBooleanExpression CreateNotLike(IExpression left, string right, string escape)
+        {
+            return new LikeExpression(left, right, escape, false);
+        }
+
+        public static IBooleanExpression CreateBetween(IExpression value, IExpression left, IExpression right)
+        {
+            return LogicExpression.CreateAND(CreateGreaterThanOrEqual(value, left), CreateLesserThanOrEqual(value, right));
+        }
+
+        public static IBooleanExpression CreateNotBetween(IExpression value, IExpression left, IExpression right)
+        {
+            return LogicExpression.CreateOR(CreateLesserThan(value, left), CreateGreaterThan(value, right));
+        }
+
+        public static IBooleanExpression CreateIn(IExpression left, ArrayList elements)
+        {
+            return new InExpression(left, elements, true);
+        }
+
+        public static IBooleanExpression CreateNotIn(IExpression left, ArrayList elements)
+        {
+            return new InExpression(left, elements, false);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/ConstantExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/ConstantExpression.cs b/src/main/csharp/Selector/ConstantExpression.cs
new file mode 100644
index 0000000..90dfd69
--- /dev/null
+++ b/src/main/csharp/Selector/ConstantExpression.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Text;
+using System.Globalization;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// Represents a constant expression.
+    /// </summary>
+    public class ConstantExpression : IExpression
+    {
+        private object value;
+        public object Value
+        {
+            get { return value; }
+        }    
+
+        public ConstantExpression(object value)
+        {
+            this.value = value;
+        }
+
+        public static ConstantExpression CreateFromDecimal(string text)
+        {
+    	    // Long integer specified ?
+    	    object value;
+            if(text.EndsWith("l") || text.EndsWith("L"))
+            {
+    		    text = text.Substring(0, text.Length - 1);
+                value = Int64.Parse(text, CultureInfo.InvariantCulture);
+            }
+            else
+            {
+                long lvalue = Int64.Parse(text, CultureInfo.InvariantCulture);
+                if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue)
+                {
+                    value = (int)lvalue;
+                }
+                else
+                {
+                    value = lvalue;
+                }
+            }
+            return new ConstantExpression(value);
+        }
+
+        public static ConstantExpression CreateFromHex(string text)
+        {
+            long lvalue = Convert.ToInt64(text.Substring(2), 16);
+
+    	    object value;
+            if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue)
+            {
+                value = (int)lvalue;
+            }
+            else
+            {
+                value = lvalue;
+            }
+            return new ConstantExpression(value);
+        }
+
+
+        public static ConstantExpression CreateFromOctal(string text)
+        {
+            long lvalue = Convert.ToInt64(text, 8);
+
+    	    object value;
+            if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue)
+            {
+                value = (int)lvalue;
+            }
+            else
+            {
+                value = lvalue;
+            }
+            return new ConstantExpression(value);
+        }
+
+        public static ConstantExpression CreateFloat(string text)
+        {
+            double value = Double.Parse(text, CultureInfo.InvariantCulture);
+            return new ConstantExpression(value);
+        }
+
+        public object Evaluate(MessageEvaluationContext message)
+        {
+            return value;
+        }
+
+        public override string ToString()
+        {
+            if(value == null)
+            {
+                return "NULL";
+            }
+            if(value is bool)
+            {
+                return (bool)value ? "TRUE" : "FALSE";
+            }
+            if(value is string)
+            {
+                return EncodeString((string)value);
+            }
+            return value.ToString();
+        }
+
+        public override int GetHashCode()
+        {
+            return (value == null ? 0 : value.GetHashCode());
+        }
+
+        /// <summary>
+        /// Encodes the value of string so that it looks like it would look like
+        /// when it was provided in a selector.
+        /// </summary>
+        /// <param name="s">String to be encoded.</param>
+        /// <return>Encoded string.</return>
+        public static string EncodeString(string s)
+        {
+            StringBuilder b = new StringBuilder();
+            b.Append('\'');
+            for(int c = 0; c < s.Length; c++)
+            {
+                char ch = s[c];
+                if(ch == '\'')
+                {
+                    b.Append(ch);
+                }
+                b.Append(ch);
+            }
+            b.Append('\'');
+            return b.ToString();
+        }
+
+        public static readonly BooleanConstantExpression NULL  = new BooleanConstantExpression(null);
+        public static readonly BooleanConstantExpression TRUE  = new BooleanConstantExpression(true);
+        public static readonly BooleanConstantExpression FALSE = new BooleanConstantExpression(false);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/DivideExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/DivideExpression.cs b/src/main/csharp/Selector/DivideExpression.cs
new file mode 100644
index 0000000..e280ec8
--- /dev/null
+++ b/src/main/csharp/Selector/DivideExpression.cs
@@ -0,0 +1,67 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a division of two expressions.
+    /// </summary>
+    public class DivideExpression : ArithmeticExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return "/"; }
+        }
+
+        public DivideExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object lvalue = Left.Evaluate(message);
+            if(lvalue == null) return null;
+
+            object rvalue = Right.Evaluate(message);
+            if(rvalue == null) return null;
+
+            AlignedNumericValues values = new AlignedNumericValues(lvalue, rvalue);
+
+            object result = null;
+
+            switch(values.TypeEnum)
+            {
+                case AlignedNumericValues.T.SByteType : result = (sbyte )values.Left / (sbyte )values.Right; break;
+                case AlignedNumericValues.T.ByteType  : result = (byte  )values.Left / (byte  )values.Right; break;
+                case AlignedNumericValues.T.CharType  : result = (char  )values.Left / (char  )values.Right; break;
+                case AlignedNumericValues.T.ShortType : result = (short )values.Left / (short )values.Right; break;
+                case AlignedNumericValues.T.UShortType: result = (ushort)values.Left / (ushort)values.Right; break;
+                case AlignedNumericValues.T.IntType   : result = (int   )values.Left / (int   )values.Right; break;
+                case AlignedNumericValues.T.UIntType  : result = (uint  )values.Left / (uint  )values.Right; break;
+                case AlignedNumericValues.T.LongType  : result = (long  )values.Left / (long  )values.Right; break;
+                case AlignedNumericValues.T.ULongType : result = (ulong )values.Left / (ulong )values.Right; break;
+                case AlignedNumericValues.T.FloatType : result = (float )values.Left / (float )values.Right; break;
+                case AlignedNumericValues.T.DoubleType: result = (double)values.Left / (double)values.Right; break;
+            }
+
+            return result;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/EqualExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/EqualExpression.cs b/src/main/csharp/Selector/EqualExpression.cs
new file mode 100644
index 0000000..0e9a792
--- /dev/null
+++ b/src/main/csharp/Selector/EqualExpression.cs
@@ -0,0 +1,47 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing an equality or inequality comparison
+    /// of two expressions.
+    /// </summary>
+    public class EqualExpression : ComparisonExpression
+    {
+        private bool notNot;
+
+        protected override string ExpressionSymbol
+        {
+            get { return notNot ? "=" : "<>"; }
+        }
+
+        public EqualExpression(IExpression left, IExpression right, bool notNot)
+            : base(left, right)
+        {
+            this.notNot = notNot;
+        }
+
+        public override bool AsBoolean(int? compared)
+        {
+            bool answer = (compared.HasValue ? compared.Value == 0 : false);
+            return notNot ? answer : !answer;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/GreaterExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/GreaterExpression.cs b/src/main/csharp/Selector/GreaterExpression.cs
new file mode 100644
index 0000000..eb264e5
--- /dev/null
+++ b/src/main/csharp/Selector/GreaterExpression.cs
@@ -0,0 +1,42 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a greater than comparison of two expressions.
+    /// </summary>
+    public class GreaterExpression : ComparisonExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return ">"; }
+        }
+
+        public GreaterExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override bool AsBoolean(int? compared)
+        {
+            return compared.HasValue ? compared.Value > 0 : false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/GreaterOrEqualExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/GreaterOrEqualExpression.cs b/src/main/csharp/Selector/GreaterOrEqualExpression.cs
new file mode 100644
index 0000000..7a456f8
--- /dev/null
+++ b/src/main/csharp/Selector/GreaterOrEqualExpression.cs
@@ -0,0 +1,43 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a greater than or equal comparison
+    /// of two expressions.
+    /// </summary>
+    public class GreaterOrEqualExpression : ComparisonExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return ">="; }
+        }
+
+        public GreaterOrEqualExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override bool AsBoolean(int? compared)
+        {
+            return compared.HasValue ? compared.Value >= 0 : false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/IBooleanExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/IBooleanExpression.cs b/src/main/csharp/Selector/IBooleanExpression.cs
new file mode 100644
index 0000000..af6c0f5
--- /dev/null
+++ b/src/main/csharp/Selector/IBooleanExpression.cs
@@ -0,0 +1,35 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// An IBooleanExpression is an expression that always
+    /// produces a boolean result.
+    /// </summary>
+    public interface IBooleanExpression : IExpression
+    {
+        /// <summary>
+        /// Checks if expression evaluates to <c>true</c>.
+        /// </summary>
+        /// <param name="message">Evaluation context.</param>
+        /// <return><c>true</c> if the expression evaluates to <c>true</c>.</return>
+        bool Matches(MessageEvaluationContext message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/IExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/IExpression.cs b/src/main/csharp/Selector/IExpression.cs
new file mode 100644
index 0000000..30fb893
--- /dev/null
+++ b/src/main/csharp/Selector/IExpression.cs
@@ -0,0 +1,35 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// Represents an expression
+    /// </summary>
+    public interface IExpression
+    {
+        /// <summary>
+        /// Evaluates the expression.
+        /// </summary>
+        /// <param name="message">Evaluation context.</param>
+        /// <return>The result of the evaluation.</return>
+        object Evaluate(MessageEvaluationContext message);
+    }
+}
+    
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/InExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/InExpression.cs b/src/main/csharp/Selector/InExpression.cs
new file mode 100644
index 0000000..cd2d7ea
--- /dev/null
+++ b/src/main/csharp/Selector/InExpression.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A boolean expression which checks if an expression value is
+    /// contained in a list of defined values.
+    /// </summary>
+    public class InExpression : BooleanUnaryExpression
+    {
+        private bool notNot;
+        private ArrayList elements;
+        private HashSet<string> hashset;
+
+        protected override string ExpressionSymbol
+        {
+            get { return notNot ? "IN" : "NOT IN"; }
+        }
+
+        public InExpression(IExpression right, ArrayList elements, bool notNot)
+            : base(right)
+        {
+            this.notNot = notNot;
+
+            this.elements = elements;
+            this.hashset = new HashSet<string>();
+
+            foreach(object element in elements)
+            {
+                hashset.Add((string)element);
+            }
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object rvalue = Right.Evaluate(message);
+
+            bool answer = false;
+            if(rvalue != null && (rvalue is string))
+            {
+                answer = hashset.Contains((string)rvalue);
+            }
+
+            return notNot ? answer : !answer;
+        }
+
+        public override string ToString()
+        {
+            StringBuilder answer = new StringBuilder();
+            answer.Append(Right);
+            answer.Append(" ");
+            answer.Append(ExpressionSymbol);
+            answer.Append(" (");
+
+            for(int i = 0; i < elements.Count; i++)
+            {
+                if(i > 0) answer.Append(", ");
+
+                string s = (string)elements[i];
+
+                answer.Append('\'');
+                for(int c = 0; c < s.Length; c++)
+                {
+                    char ch = s[c];
+                    if(ch == '\'')
+                    {
+                        answer.Append(ch);
+                    }
+                    answer.Append(ch);
+                }
+                answer.Append('\'');
+            }
+
+            answer.Append(")");
+            return answer.ToString();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/IsNullExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/IsNullExpression.cs b/src/main/csharp/Selector/IsNullExpression.cs
new file mode 100644
index 0000000..28d89a2
--- /dev/null
+++ b/src/main/csharp/Selector/IsNullExpression.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Text;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A boolean expression which checks if an expression value is null.
+    /// </summary>
+    public class IsNullExpression : BooleanUnaryExpression
+    {
+        private bool notNot;
+
+        protected override string ExpressionSymbol
+        {
+            get { return notNot ? "IS NULL" : "IS NOT NULL"; }
+        }
+
+        public IsNullExpression(IExpression right, bool notNot)
+            : base(right)
+        {
+            this.notNot = notNot;
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object rvalue = Right.Evaluate(message);
+
+            bool answer = (rvalue == null || rvalue == ConstantExpression.NULL);
+
+            return notNot ? answer : !answer;
+        }
+
+        public override string ToString()
+        {
+            StringBuilder answer = new StringBuilder();
+            answer.Append(Right);
+            answer.Append(" ");
+            answer.Append(ExpressionSymbol);
+            return answer.ToString();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/LesserExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/LesserExpression.cs b/src/main/csharp/Selector/LesserExpression.cs
new file mode 100644
index 0000000..4be2c9d
--- /dev/null
+++ b/src/main/csharp/Selector/LesserExpression.cs
@@ -0,0 +1,42 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a lesser than comparison of two expressions.
+    /// </summary>
+    public class LesserExpression : ComparisonExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return "<"; }
+        }
+
+        public LesserExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override bool AsBoolean(int? compared)
+        {
+            return compared.HasValue ? compared.Value < 0 : false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/LesserOrEqualExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/LesserOrEqualExpression.cs b/src/main/csharp/Selector/LesserOrEqualExpression.cs
new file mode 100644
index 0000000..abdc7e5
--- /dev/null
+++ b/src/main/csharp/Selector/LesserOrEqualExpression.cs
@@ -0,0 +1,43 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a lesser than or equal comparison
+    /// of two expressions.
+    /// </summary>
+    public class LesserOrEqualExpression : ComparisonExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return "<="; }
+        }
+
+        public LesserOrEqualExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override bool AsBoolean(int? compared)
+        {
+            return compared.HasValue ? compared.Value <= 0 : false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/LikeExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/LikeExpression.cs b/src/main/csharp/Selector/LikeExpression.cs
new file mode 100644
index 0000000..8317bd6
--- /dev/null
+++ b/src/main/csharp/Selector/LikeExpression.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Globalization;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a string matching comparison.
+    /// </summary>
+    public class LikeExpression : BooleanUnaryExpression
+    {
+        private bool notNot;
+        private Regex pattern;
+
+        protected override string ExpressionSymbol
+        {
+            get { return notNot ? "LIKE" : "NOT LIKE"; }
+        }
+
+        public LikeExpression(IExpression left, string like, string escape, bool notNot)
+            : base(left)
+        {
+            this.notNot = notNot;
+
+            bool doEscape = false;
+            char escapeChar = '%';
+
+            if(escape != null)
+            {
+                if(escape.Length != 1)
+                {
+                    throw new ApplicationException("The ESCAPE string litteral is invalid.  It can only be one character.  Litteral used: " + escape);
+                }
+                doEscape = true;
+                escapeChar = escape[0];
+            }
+
+            StringBuilder temp = new StringBuilder();
+            StringBuilder regexp = new StringBuilder(like.Length * 2);
+            regexp.Append("^"); // The beginning of the input
+            for(int c = 0; c < like.Length; c++)
+            {
+                char ch = like[c];
+                if(doEscape && (ch == escapeChar))
+                {
+                    c++;
+                    if(c >= like.Length)
+                    {
+                        // nothing left to escape...
+                        break;
+                    }
+                    temp.Append(like[c]);
+                }
+                else if(ch == '%')
+                {
+                    if(temp.Length > 0)
+                    {
+                        regexp.Append(Regex.Escape(temp.ToString()));
+                        temp.Length = 0;
+                    }
+                    regexp.Append(".*?"); // Do a non-greedy match 
+                }
+                else if(c == '_')
+                {
+                    if(temp.Length > 0)
+                    {
+                        regexp.Append(Regex.Escape(temp.ToString()));
+                        temp.Length = 0;
+                    }
+                    regexp.Append("."); // match one 
+                }
+                else
+                {
+                    temp.Append(ch);
+                }
+            }
+            if(temp.Length > 0)
+            {
+                regexp.Append(Regex.Escape(temp.ToString()));
+            }
+            regexp.Append("$"); // The end of the input
+
+            pattern = new Regex(regexp.ToString(), RegexOptions.Singleline | RegexOptions.Compiled);
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object rvalue = this.Right.Evaluate(message);
+
+            bool answer = false;
+            if(rvalue != null)
+            {
+                if(rvalue is string)
+                {
+                    answer = pattern.IsMatch((string)rvalue);
+                }
+                else
+                {
+                    //throw new ApplicationException("LIKE can only operate on string identifiers. LIKE attemped on " + rvalue.GetType().ToString());
+                }
+            }
+
+            return notNot ? answer : !answer;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/LogicExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/LogicExpression.cs b/src/main/csharp/Selector/LogicExpression.cs
new file mode 100644
index 0000000..61617a4
--- /dev/null
+++ b/src/main/csharp/Selector/LogicExpression.cs
@@ -0,0 +1,48 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a logical combination of two objects.
+    /// </summary>
+    public abstract class LogicExpression : BinaryExpression, IBooleanExpression
+    {
+        public LogicExpression(IBooleanExpression left, IBooleanExpression right)
+            : base(left, right)
+        {
+        }
+
+        public bool Matches(MessageEvaluationContext message)
+        {
+            object value = Evaluate(message);
+            return value != null && (bool)value;            
+        }
+
+        public static IBooleanExpression CreateOR(IBooleanExpression left, IBooleanExpression right)
+        {
+            return new ORExpression(left, right);
+        }
+
+        public static IBooleanExpression CreateAND(IBooleanExpression left, IBooleanExpression right)
+        {
+            return new ANDExpression(left, right);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/MessageEvaluationContext.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/MessageEvaluationContext.cs b/src/main/csharp/Selector/MessageEvaluationContext.cs
new file mode 100644
index 0000000..054d911
--- /dev/null
+++ b/src/main/csharp/Selector/MessageEvaluationContext.cs
@@ -0,0 +1,78 @@
+using System;
+using Apache.NMS;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// MessageEvaluationContext is used to cache selection results.
+    /// 
+    /// A message usually has multiple selectors applied against it. Some selector
+    /// have a high cost of evaluating against the message. Those selectors may whish
+    /// to cache evaluation results associated with the message in the
+    /// MessageEvaluationContext.
+    /// </summary>
+    public class MessageEvaluationContext
+    {
+        private IMessage nmsMessage;
+        public IMessage Message
+        {
+            get { return nmsMessage; }
+            set { nmsMessage = value; }
+        }
+
+        public MessageEvaluationContext(IMessage message)
+        {
+            nmsMessage = message;
+        }
+
+        public object GetProperty(string name)
+        {
+            if(name.Length > 3 && 
+               string.Compare(name.Substring(0, 3), "JMS", true) == 0)
+            {
+                if(string.Compare(name, "JMSCorrelationID", true) == 0)
+                {
+                    return nmsMessage.NMSCorrelationID;
+                }
+                if(string.Compare(name, "JMSMessageID", true) == 0)
+                {
+                    return nmsMessage.NMSMessageId;
+                }
+                if(string.Compare(name, "JMSPriority", true) == 0)
+                {
+                    return nmsMessage.NMSPriority;
+                }
+                if(string.Compare(name, "JMSTimestamp", true) == 0)
+                {
+                    return nmsMessage.NMSTimestamp;
+                }
+                if(string.Compare(name, "JMSType", true) == 0)
+                {
+                    return nmsMessage.NMSType;
+                }
+                if(string.Compare(name, "JMSDeliveryMode", true) == 0)
+                {
+                    return nmsMessage.NMSDeliveryMode;
+                }
+            }
+            return nmsMessage.Properties[name];
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/MinusExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/MinusExpression.cs b/src/main/csharp/Selector/MinusExpression.cs
new file mode 100644
index 0000000..260e5e8
--- /dev/null
+++ b/src/main/csharp/Selector/MinusExpression.cs
@@ -0,0 +1,67 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a substraction of two expressions.
+    /// </summary>
+    public class MinusExpression : ArithmeticExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return "-"; }
+        }
+
+        public MinusExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object lvalue = Left.Evaluate(message);
+            if(lvalue == null) return null;
+
+            object rvalue = Right.Evaluate(message);
+            if(rvalue == null) return null;
+
+            AlignedNumericValues values = new AlignedNumericValues(lvalue, rvalue);
+
+            object result = null;
+
+            switch(values.TypeEnum)
+            {
+                case AlignedNumericValues.T.SByteType : result = (sbyte )values.Left - (sbyte )values.Right; break;
+                case AlignedNumericValues.T.ByteType  : result = (byte  )values.Left - (byte  )values.Right; break;
+                case AlignedNumericValues.T.CharType  : result = (char  )values.Left - (char  )values.Right; break;
+                case AlignedNumericValues.T.ShortType : result = (short )values.Left - (short )values.Right; break;
+                case AlignedNumericValues.T.UShortType: result = (ushort)values.Left - (ushort)values.Right; break;
+                case AlignedNumericValues.T.IntType   : result = (int   )values.Left - (int   )values.Right; break;
+                case AlignedNumericValues.T.UIntType  : result = (uint  )values.Left - (uint  )values.Right; break;
+                case AlignedNumericValues.T.LongType  : result = (long  )values.Left - (long  )values.Right; break;
+                case AlignedNumericValues.T.ULongType : result = (ulong )values.Left - (ulong )values.Right; break;
+                case AlignedNumericValues.T.FloatType : result = (float )values.Left - (float )values.Right; break;
+                case AlignedNumericValues.T.DoubleType: result = (double)values.Left - (double)values.Right; break;
+            }
+
+            return result;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/ModExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/ModExpression.cs b/src/main/csharp/Selector/ModExpression.cs
new file mode 100644
index 0000000..386c08d
--- /dev/null
+++ b/src/main/csharp/Selector/ModExpression.cs
@@ -0,0 +1,67 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a modulo of two expressions.
+    /// </summary>
+    public class ModExpression : ArithmeticExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return "%"; }
+        }
+
+        public ModExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object lvalue = Left.Evaluate(message);
+            if(lvalue == null) return null;
+
+            object rvalue = Right.Evaluate(message);
+            if(rvalue == null) return null;
+
+            AlignedNumericValues values = new AlignedNumericValues(lvalue, rvalue);
+
+            object result = null;
+
+            switch(values.TypeEnum)
+            {
+                case AlignedNumericValues.T.SByteType : result = (sbyte )values.Left % (sbyte )values.Right; break;
+                case AlignedNumericValues.T.ByteType  : result = (byte  )values.Left % (byte  )values.Right; break;
+                case AlignedNumericValues.T.CharType  : result = (char  )values.Left % (char  )values.Right; break;
+                case AlignedNumericValues.T.ShortType : result = (short )values.Left % (short )values.Right; break;
+                case AlignedNumericValues.T.UShortType: result = (ushort)values.Left % (ushort)values.Right; break;
+                case AlignedNumericValues.T.IntType   : result = (int   )values.Left % (int   )values.Right; break;
+                case AlignedNumericValues.T.UIntType  : result = (uint  )values.Left % (uint  )values.Right; break;
+                case AlignedNumericValues.T.LongType  : result = (long  )values.Left % (long  )values.Right; break;
+                case AlignedNumericValues.T.ULongType : result = (ulong )values.Left % (ulong )values.Right; break;
+                case AlignedNumericValues.T.FloatType : result = (float )values.Left % (float )values.Right; break;
+                case AlignedNumericValues.T.DoubleType: result = (double)values.Left % (double)values.Right; break;
+            }
+
+            return result;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-msmq/blob/16d8f06d/src/main/csharp/Selector/MultiplyExpression.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Selector/MultiplyExpression.cs b/src/main/csharp/Selector/MultiplyExpression.cs
new file mode 100644
index 0000000..0009092
--- /dev/null
+++ b/src/main/csharp/Selector/MultiplyExpression.cs
@@ -0,0 +1,67 @@
+using System;
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.NMS.Selector
+{
+    /// <summary>
+    /// A filter performing a multiplication of two expressions.
+    /// </summary>
+    public class MultiplyExpression : ArithmeticExpression
+    {
+        protected override string ExpressionSymbol
+        {
+            get { return "*"; }
+        }
+
+        public MultiplyExpression(IExpression left, IExpression right)
+            : base(left, right)
+        {
+        }
+
+        public override object Evaluate(MessageEvaluationContext message)
+        {
+            object lvalue = Left.Evaluate(message);
+            if(lvalue == null) return null;
+
+            object rvalue = Right.Evaluate(message);
+            if(rvalue == null) return null;
+
+            AlignedNumericValues values = new AlignedNumericValues(lvalue, rvalue);
+
+            object result = null;
+
+            switch(values.TypeEnum)
+            {
+                case AlignedNumericValues.T.SByteType : result = (sbyte )values.Left * (sbyte )values.Right; break;
+                case AlignedNumericValues.T.ByteType  : result = (byte  )values.Left * (byte  )values.Right; break;
+                case AlignedNumericValues.T.CharType  : result = (char  )values.Left * (char  )values.Right; break;
+                case AlignedNumericValues.T.ShortType : result = (short )values.Left * (short )values.Right; break;
+                case AlignedNumericValues.T.UShortType: result = (ushort)values.Left * (ushort)values.Right; break;
+                case AlignedNumericValues.T.IntType   : result = (int   )values.Left * (int   )values.Right; break;
+                case AlignedNumericValues.T.UIntType  : result = (uint  )values.Left * (uint  )values.Right; break;
+                case AlignedNumericValues.T.LongType  : result = (long  )values.Left * (long  )values.Right; break;
+                case AlignedNumericValues.T.ULongType : result = (ulong )values.Left * (ulong )values.Right; break;
+                case AlignedNumericValues.T.FloatType : result = (float )values.Left * (float )values.Right; break;
+                case AlignedNumericValues.T.DoubleType: result = (double)values.Left * (double)values.Right; break;
+            }
+
+            return result;
+        }
+    }
+}


Mime
View raw message