public WhereClauseVisitor(MemberFilterAggregator aggregator, FilterGroup filter)
 {
     _aggregator = aggregator;
       _filter = filter;
 }
 public static Expression Visit(Expression expression, MemberFilterAggregator aggregator, FilterGroup filter = null)
 {
     return new WhereClauseVisitor(aggregator, filter).Visit(expression);
 }
        private void ProcessValue(ConstantExpression item, FilterGroup root)
        {
            if (root == null)
            throw new ArgumentException("the filter should be of specific type");
              var filter = root.Filters.Peek() as Filter;
              if (filter == null)
            return;

              switch (filter.FilterBy)
              {
            case FilterBy.NotSet:
              root.Filters.Pop();
              break;
            case FilterBy.BindingFlags:
              var intValue = (int)item.Value;
              filter.BindingFlags = BindingFlagsMappinsg[intValue - 1];
              break;
            case FilterBy.Name:
              filter.Name = item.Value.ToString();
              break;
            case FilterBy.Type:
              filter.Type = item.Value as Type;
              break;
            case FilterBy.MemberType:
              filter.MemberTypes = (MemberTypes)item.Value;
              break;
            default:
              root.Filters.Pop();
              break;
              }
        }
        private MemberCacheDescriptor ToDescriptor(FilterGroup group)
        {
            var descriptors = new List<MemberCacheDescriptor>();

              while (group.Filters.Any())
              {
            var filter = group.Filters.Pop();
            switch (filter.FilterType)
            {
              case FilterType.Group:
            descriptors.Add(ToDescriptor((FilterGroup)filter));
            break;
              case FilterType.Filter:
            descriptors.Add(ToDescriptor((Filter)filter));
            break;
              default:
            throw new ArgumentOutOfRangeException();
            }
              }

              switch (group.GroupKind)
              {
            case FilterGroupKind.And:
            case FilterGroupKind.Root:
              return MergeDescriptorsUsingAnd(descriptors);
            case FilterGroupKind.Or:
              return MergeDescriptorsUsingOr(descriptors);
            default:
              throw new ArgumentOutOfRangeException();
              }
        }
 private FilterGroup ProcessOr(FilterGroup root)
 {
     var group = new FilterGroup {GroupKind = FilterGroupKind.Or};
       root.Filters.Push(group);
       return group;
 }
        private void ProcessMember(MemberExpression expression, FilterGroup root)
        {
            var filterBy = ResolvePropertyType(expression.Member);
              if (filterBy == FilterBy.Unknown && root.Filters.Peek() is Filter)
            root.Filters.Pop();

              var filter = (Filter)root.Filters.Peek();
              filter.FilterBy = filterBy;
        }
 private void ProcessCondition(FilterExpression filterExpression, FilterGroup root)
 {
     var filter = new Filter();
       root.Filters.Push(filter);
       filter.FilterExpression = filterExpression;
 }
 private MemberCacheDescriptor ParseFilterTree(FilterGroup root)
 {
     return ToDescriptor(root);
 }
 public virtual FilterGroup Push(Expression item, FilterGroup root = null)
 {
     root = root ?? _filterRoot;
       switch (item.NodeType)
       {
     case ExpressionType.Or:
     case ExpressionType.OrElse:
       return ProcessOr(root);
     case ExpressionType.NotEqual:
     case ExpressionType.Equal:
       ProcessCondition((FilterExpression)(int)item.NodeType, root);
       break;
     case ExpressionType.MemberAccess:
       ProcessMember(item as MemberExpression, root);
       break;
     case ExpressionType.Constant:
       ProcessValue(item as ConstantExpression, root);
       break;
       }
       return root;
 }