/// <summary>
    /// Adds the serch root.
    /// </summary>
    /// <param name="query">The query.</param>
    /// <param name="searchRoot">The search root.</param>
    protected virtual void AddSearchRoot(LuceneSearch.BooleanQuery query, string searchRoot)
    {
      if (!string.IsNullOrEmpty(searchRoot))
      {
        if (ID.IsID(searchRoot))
        {
          searchRoot = this.GetItemPath(new ID(searchRoot));
        }
        else
        {
          Item rootItem = this.Database.SelectSingleItem(searchRoot);
          if (rootItem != null)
          {
            searchRoot = this.GetItemPath(rootItem.ID);
          }
        }

        query.Add(new LuceneSearch.TermQuery(new Term(Sitecore.Search.BuiltinFields.Path, searchRoot)), LuceneSearch.Occur.MUST);
      }
    }
 /// <summary>
 /// Adds the simple query.
 /// </summary>
 /// <param name="query">The boolean query.</param>
 /// <param name="key">The field key.</param>
 /// <param name="value">The field value.</param>
 /// <param name="condition">The condition.</param>
 /// <param name="isFirst">if set to <c>true</c> [is first].</param>
 private void AddIdQuery(LuceneSearch.BooleanQuery query, string key, string value, QueryCondition condition)
 {
   value = this.GetItemPath(new ID(value));
   LuceneSearch.Occur occurrence = this.GetOccur(condition);
   query.Add(new LuceneSearch.TermQuery(new Term(key, value)), occurrence);
 }
    /// <summary>
    /// Adds the content sub query.
    /// </summary>
    /// <param name="query">The boolean query.</param>
    /// <param name="key">The field key.</param>
    /// <param name="value">The field value.</param>
    /// <param name="matchVariant">The match variant.</param>
    /// <param name="condition">The condition.</param>
    /// <param name="isFirst">if set to <c>true</c> [is first].</param>
    private void AddContentSubQuery(LuceneSearch.BooleanQuery query, string key, string value, MatchVariant matchVariant, QueryCondition condition)
    {
      if (matchVariant == MatchVariant.NotEquals)
      {
        query.Add(new LuceneSearch.TermQuery(new Term(key, value)), LuceneSearch.Occur.MUST_NOT);
        return;
      }

      LuceneSearch.Occur occurrence = this.GetOccur(condition);

      LuceneSearch.TermRangeQuery rangeQuery = this.GetRangeQuery(key, value, matchVariant);
      if (rangeQuery != null)
      {
        query.Add(rangeQuery, occurrence);
        return;
      }

      string[] keywords = value.Split(' ');
      if (keywords.Length > 1)
      {
        LuceneSearch.PhraseQuery phraseQuery = new Lucene.Net.Search.PhraseQuery();

        foreach (string keyword in keywords)
        {
          phraseQuery.Add(new Term(key, keyword));
        }

        query.Add(phraseQuery, occurrence);
      }
      else if (matchVariant == MatchVariant.Like)
      {
        query.Add(new LuceneSearch.WildcardQuery(new Term(key, value + "*")), occurrence);
      }
      else
      {
        query.Add(new LuceneSearch.TermQuery(new Term(key, value)), occurrence);
      }
    }
    /// <summary>
    /// Builds the query.
    /// </summary>
    /// <param name="query">The result query.</param>
    /// <param name="node">The query node.</param>
    protected virtual void BuildQuery(LuceneSearch.BooleanQuery query, QueryNode node)
    {
      Query subQuery = node.Element as Query;
      if (subQuery != null && !subQuery.IsEmpty())
      {
        LuceneSearch.BooleanQuery booleanQuery = new LuceneSearch.BooleanQuery();

        if (!string.IsNullOrEmpty(subQuery.SearchRoot))
        {
          this.AddSearchRoot(booleanQuery, subQuery.SearchRoot);
        }

        this.BuildQuery(booleanQuery, subQuery.FirstNode);
        LuceneSearch.Occur occurance = LuceneSearch.Occur.MUST;
        if (node.IsFirst)
        {
          if (!node.IsLast && (node.NextNode.Element is Condition))
          {
            occurance = this.GetOccur(((Condition)node.NextNode.Element).QueryCondition);
          }
        }
        else
        {
          if (!node.IsFirst && (node.PreviousNode.Element is Condition))
          {
            occurance = this.GetOccur(((Condition)node.PreviousNode.Element).QueryCondition);
          }
        }

        query.Add(booleanQuery, occurance);
      }
      else if (node.Element is AttributeQuery || node.Element is FieldQuery)
      {
        QueryCondition condition = QueryCondition.And;
        
        if (node.IsFirst)
        {
          if (!node.IsLast && (node.NextNode.Element is Condition))
          {
            condition = ((Condition)node.NextNode.Element).QueryCondition;
          }          
        }
        else
        {
          if (!node.IsFirst && (node.PreviousNode.Element is Condition))
          {
            condition = ((Condition)node.PreviousNode.Element).QueryCondition;
          }
        }

        this.AddSubQuery(query, node.Element as SubQuery, condition);
      }

      if (!node.IsLast)
      {
        this.BuildQuery(query, node.NextNode);
      }

      this.resultQuery = query;
    }