public HFilter parse()
            {
                HFilter f = condOr();

                verify(HaystackToken.eof);
                return(f);
            }
        /** Equality is based on string encoding */
        public bool hequals(object that)
        {
            if (!(that is HFilter))
            {
                return(false);
            }
            HFilter filthat = (HFilter)that;

            return(ToString().CompareTo(filthat.ToString()) == 0);
        }
            private HFilter condAnd()
            {
                HFilter lhs = term();

                if (!isKeyword("and"))
                {
                    return(lhs);
                }
                consume();
                return(lhs.and(condAnd()));
            }
            private HFilter condOr()
            {
                HFilter lhs = condAnd();

                if (!isKeyword("or"))
                {
                    return(lhs);
                }
                consume();
                return(lhs.or(condOr()));
            }
            private HFilter term()
            {
                if (m_tokCur == HaystackToken.lparen)
                {
                    consume();
                    HFilter f = condOr();
                    consume(HaystackToken.rparen);
                    return(f);
                }

                if (isKeyword("not") && m_tokPeek == HaystackToken.id)
                {
                    consume();
                    return(new Missing(path()));
                }

                Path p = path();

                if (m_tokCur == HaystackToken.eq)
                {
                    consume(); return(new Eq(p, val()));
                }
                if (m_tokCur == HaystackToken.notEq)
                {
                    consume(); return(new Ne(p, val()));
                }
                if (m_tokCur == HaystackToken.lt)
                {
                    consume(); return(new Lt(p, val()));
                }
                if (m_tokCur == HaystackToken.ltEq)
                {
                    consume(); return(new Le(p, val()));
                }
                if (m_tokCur == HaystackToken.gt)
                {
                    consume(); return(new Gt(p, val()));
                }
                if (m_tokCur == HaystackToken.gtEq)
                {
                    consume(); return(new Ge(p, val()));
                }

                return(new Has(p));
            }
 public Or(HFilter a, HFilter b) : base(a, b)
 {
     m_a = a;
     m_b = b;
 }
 public CompoundFilter(HFilter a, HFilter b)
 {
     m_a = a;
     m_b = b;
 }
 /**
  * Return a query which is the logical-or of this and that query.
  */
 public HFilter or(HFilter that)
 {
     return(new Or(this, that));
 }
 /**
  * Return a query which is the logical-and of this and that query.
  */
 public HFilter and(HFilter that)
 {
     return(new And(this, that));
 }