public override void MatchEvent(
            EventBean theEvent,
            ICollection<FilterHandle> matches,
            ExprEvaluatorContext ctx)
        {
            var objAttributeValue = Lookupable.Eval.Eval(theEvent, ctx);
            if (InstrumentationHelper.ENABLED) {
                InstrumentationHelper.Get().QFilterReverseIndex(this, objAttributeValue);
            }

            if (objAttributeValue == null) {
                if (InstrumentationHelper.ENABLED) {
                    InstrumentationHelper.Get().AFilterReverseIndex(false);
                }

                return;
            }

            double attributeValue = objAttributeValue.AsDouble();

            if (FilterOperator == FilterOperator.NOT_RANGE_CLOSED) { // include all endpoints
                foreach (var entry in Ranges) {
                    if (attributeValue < entry.Key.Min ||
                        attributeValue > entry.Key.Max) {
                        entry.Value.MatchEvent(theEvent, matches, ctx);
                    }
                }
            }
            else if (FilterOperator == FilterOperator.NOT_RANGE_OPEN) { // include neither endpoint
                foreach (var entry in Ranges) {
                    if (attributeValue <= entry.Key.Min ||
                        attributeValue >= entry.Key.Max) {
                        entry.Value.MatchEvent(theEvent, matches, ctx);
                    }
                }
            }
            else if (FilterOperator == FilterOperator.NOT_RANGE_HALF_CLOSED) { // include high endpoint not low endpoint
                foreach (var entry in Ranges) {
                    if (attributeValue <= entry.Key.Min ||
                        attributeValue > entry.Key.Max) {
                        entry.Value.MatchEvent(theEvent, matches, ctx);
                    }
                }
            }
            else if (FilterOperator == FilterOperator.NOT_RANGE_HALF_OPEN) { // include low endpoint not high endpoint
                foreach (var entry in Ranges) {
                    if (attributeValue < entry.Key.Min ||
                        attributeValue >= entry.Key.Max) {
                        entry.Value.MatchEvent(theEvent, matches, ctx);
                    }
                }
            }
            else {
                throw new IllegalStateException("Invalid filter operator " + FilterOperator);
            }

            RangesNullEndpoints?.MatchEvent(theEvent, matches, ctx);

            if (InstrumentationHelper.ENABLED) {
                InstrumentationHelper.Get().AFilterReverseIndex(null);
            }
        }
        public override void MatchEvent(
            EventBean theEvent,
            ICollection<FilterHandle> matches,
            ExprEvaluatorContext ctx)
        {
            object objAttributeValue = Lookupable.Eval.Eval(theEvent, ctx);
            if (InstrumentationHelper.ENABLED) {
                InstrumentationHelper.Get().QFilterReverseIndex(this, objAttributeValue);
            }

            if (objAttributeValue == null) {
                if (InstrumentationHelper.ENABLED) {
                    InstrumentationHelper.Get().AFilterReverseIndex(false);
                }

                return;
            }

            var attributeValue = (string) objAttributeValue;

            if (FilterOperator == FilterOperator.NOT_RANGE_CLOSED) {
                // include all endpoints
                foreach (var entry in Ranges) {
                    if (string.Compare(entry.Key.Min, attributeValue, StringComparison.Ordinal) > 0 || 
                        string.Compare(entry.Key.Max, attributeValue, StringComparison.Ordinal) < 0) {
                        entry.Value.MatchEvent(theEvent, matches, ctx);
                    }
                }
            }
            else if (FilterOperator == FilterOperator.NOT_RANGE_OPEN) { // include neither endpoint
                foreach (var entry in Ranges) {
                    if (string.Compare(entry.Key.Min, attributeValue, StringComparison.Ordinal) >= 0 || 
                        string.Compare(entry.Key.Max, attributeValue, StringComparison.Ordinal) <= 0) {
                        entry.Value.MatchEvent(theEvent, matches, ctx);
                    }
                }
            }
            else if (FilterOperator == FilterOperator.NOT_RANGE_HALF_CLOSED) {
                // include high endpoint not low endpoint
                foreach (var entry in Ranges) {
                    if (string.Compare(entry.Key.Min, attributeValue, StringComparison.Ordinal) >= 0 || 
                        string.Compare(entry.Key.Max, attributeValue, StringComparison.Ordinal) < 0) {
                        entry.Value.MatchEvent(theEvent, matches, ctx);
                    }
                }
            }
            else if (FilterOperator == FilterOperator.NOT_RANGE_HALF_OPEN) {
                // include low endpoint not high endpoint
                foreach (var entry in Ranges) {
                    if (string.Compare(entry.Key.Min, attributeValue, StringComparison.Ordinal) > 0 || 
                        string.Compare(entry.Key.Max, attributeValue, StringComparison.Ordinal) <= 0) {
                        entry.Value.MatchEvent(theEvent, matches, ctx);
                    }
                }
            }
            else {
                throw new IllegalStateException("Invalid filter operator " + FilterOperator);
            }
            
            if (RangesNullEndpoints != null) {
                RangesNullEndpoints.MatchEvent(theEvent, matches, ctx);
            }

            if (InstrumentationHelper.ENABLED) {
                InstrumentationHelper.Get().AFilterReverseIndex(null);
            }
        }