LuceneObjectPtr FilteredQuery::clone(LuceneObjectPtr other)
 {
     LuceneObjectPtr clone = other ? other : newLucene<FilteredQuery>(query, filter);
     FilteredQueryPtr cloneQuery(boost::dynamic_pointer_cast<FilteredQuery>(Query::clone(clone)));
     cloneQuery->query = query;
     cloneQuery->filter = filter;
     return cloneQuery;
 }
 LuceneObjectPtr DisjunctionMaxQuery::clone(LuceneObjectPtr other)
 {
     LuceneObjectPtr clone = Query::clone(other ? other : newLucene<DisjunctionMaxQuery>());
     DisjunctionMaxQueryPtr cloneQuery(boost::dynamic_pointer_cast<DisjunctionMaxQuery>(clone));
     cloneQuery->tieBreakerMultiplier = tieBreakerMultiplier;
     cloneQuery->disjuncts = Collection<QueryPtr>::newInstance(disjuncts.begin(), disjuncts.end());
     return cloneQuery;
 }
LuceneObjectPtr WildcardQuery::clone(const LuceneObjectPtr& other) {
    LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene<WildcardQuery>(term));
    WildcardQueryPtr cloneQuery(boost::dynamic_pointer_cast<WildcardQuery>(clone));
    cloneQuery->termContainsWildcard = termContainsWildcard;
    cloneQuery->termIsPrefix = termIsPrefix;
    cloneQuery->term = term;
    return cloneQuery;
}
LuceneObjectPtr FuzzyQuery::clone(const LuceneObjectPtr& other) {
    LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene<FuzzyQuery>(term));
    FuzzyQueryPtr cloneQuery(boost::dynamic_pointer_cast<FuzzyQuery>(clone));
    cloneQuery->minimumSimilarity = minimumSimilarity;
    cloneQuery->prefixLength = prefixLength;
    cloneQuery->termLongEnough = termLongEnough;
    cloneQuery->term = term;
    return cloneQuery;
}
 LuceneObjectPtr PhraseQuery::clone(LuceneObjectPtr other)
 {
     LuceneObjectPtr clone = other ? other : newLucene<PhraseQuery>();
     PhraseQueryPtr cloneQuery(boost::dynamic_pointer_cast<PhraseQuery>(Query::clone(clone)));
     cloneQuery->field = field;
     cloneQuery->terms = terms;
     cloneQuery->positions = positions;
     cloneQuery->maxPosition = maxPosition;
     cloneQuery->slop = slop;
     return cloneQuery;
 }
LuceneObjectPtr NumericRangeQuery::clone(const LuceneObjectPtr& other) {
    LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene<NumericRangeQuery>(field, precisionStep, valSize, min, max, minInclusive, maxInclusive));
    NumericRangeQueryPtr cloneQuery(boost::dynamic_pointer_cast<NumericRangeQuery>(clone));
    cloneQuery->field = field;
    cloneQuery->precisionStep = precisionStep;
    cloneQuery->valSize = valSize;
    cloneQuery->min = min;
    cloneQuery->max = max;
    cloneQuery->minInclusive = minInclusive;
    cloneQuery->maxInclusive = maxInclusive;
    return cloneQuery;
}
 QueryPtr FilteredQuery::rewrite(IndexReaderPtr reader)
 {
     QueryPtr rewritten(query->rewrite(reader));
     if (rewritten != query)
     {
         FilteredQueryPtr cloneQuery(boost::dynamic_pointer_cast<FilteredQuery>(clone()));
         cloneQuery->query = rewritten;
         return cloneQuery;
     }
     else
         return shared_from_this();
 }