////////////////////////////////////////////////////////////////

        // Returns the lists of terms in the query
        private ArrayList AssembleQuery(Query query,
                                        QueryPartHook query_part_hook,
                                        HitFilter hit_filter,
                                        out ArrayList primary_required_part_queries,
                                        out ArrayList secondary_required_part_queries,
                                        out LNS.BooleanQuery primary_prohibited_part_query,
                                        out LNS.BooleanQuery secondary_prohibited_part_query,
                                        out AndHitFilter all_hit_filters)
        {
            primary_required_part_queries   = null;
            secondary_required_part_queries = null;
            primary_prohibited_part_query   = null;
            secondary_prohibited_part_query = null;

            all_hit_filters = new AndHitFilter();
            if (hit_filter != null)
            {
                all_hit_filters.Add(hit_filter);
            }

            ArrayList term_list = new ArrayList();

            foreach (QueryPart part in query.Parts)
            {
                LNS.Query primary_part_query;
                LNS.Query secondary_part_query;
                HitFilter part_hit_filter;
                QueryPartToQuery(part,
                                 false,                  // we want both primary and secondary queries
                                 part.Logic == QueryPartLogic.Required ? term_list : null,
                                 query_part_hook,
                                 out primary_part_query,
                                 out secondary_part_query,
                                 out part_hit_filter);

                if (primary_part_query == null)
                {
                    continue;
                }

                switch (part.Logic)
                {
                case QueryPartLogic.Required:
                    if (primary_required_part_queries == null)
                    {
                        primary_required_part_queries   = new ArrayList();
                        secondary_required_part_queries = new ArrayList();
                    }
                    primary_required_part_queries.Add(primary_part_query);
                    secondary_required_part_queries.Add(secondary_part_query);

                    if (part_hit_filter != null)
                    {
                        all_hit_filters.Add(part_hit_filter);
                    }

                    break;

                case QueryPartLogic.Prohibited:
                    if (primary_prohibited_part_query == null)
                    {
                        primary_prohibited_part_query = new LNS.BooleanQuery();
                    }
                    primary_prohibited_part_query.Add(primary_part_query, LNS.BooleanClause.Occur.SHOULD);

                    if (secondary_part_query != null)
                    {
                        if (secondary_prohibited_part_query == null)
                        {
                            secondary_prohibited_part_query = new LNS.BooleanQuery();
                        }
                        secondary_prohibited_part_query.Add(secondary_part_query, LNS.BooleanClause.Occur.SHOULD);
                    }

                    if (part_hit_filter != null)
                    {
                        NotHitFilter nhf;
                        nhf = new NotHitFilter(part_hit_filter);
                        all_hit_filters.Add(new HitFilter(nhf.HitFilter));
                    }

                    break;
                }
            }

            return(term_list);
        }
		////////////////////////////////////////////////////////////////

		// Returns the lists of terms in the query
		private ArrayList AssembleQuery (Query			query,
						 QueryPartHook		query_part_hook,
					    	 HitFilter		hit_filter,
					    	 out ArrayList		primary_required_part_queries,
					    	 out ArrayList		secondary_required_part_queries,
					    	 out LNS.BooleanQuery	primary_prohibited_part_query,
					    	 out LNS.BooleanQuery	secondary_prohibited_part_query,
						 out AndHitFilter	all_hit_filters)
		{
			primary_required_part_queries = null;
			secondary_required_part_queries = null;
			primary_prohibited_part_query = null;
			secondary_prohibited_part_query = null;

			all_hit_filters = new AndHitFilter ();
			if (hit_filter != null)
				all_hit_filters.Add (hit_filter);

			ArrayList term_list = new ArrayList ();

			foreach (QueryPart part in query.Parts) {
				LNS.Query primary_part_query;
				LNS.Query secondary_part_query;
				HitFilter part_hit_filter;
				QueryPartToQuery (part,
						  false, // we want both primary and secondary queries
						  part.Logic == QueryPartLogic.Required ? term_list : null,
						  query_part_hook,
						  out primary_part_query,
						  out secondary_part_query,
						  out part_hit_filter);

				if (primary_part_query == null)
					continue;

				switch (part.Logic) {
					
				case QueryPartLogic.Required:
					if (primary_required_part_queries == null) {
						primary_required_part_queries = new ArrayList ();
						secondary_required_part_queries = new ArrayList ();
					}
					primary_required_part_queries.Add (primary_part_query);
					secondary_required_part_queries.Add (secondary_part_query);
					
					if (part_hit_filter != null)
						all_hit_filters.Add (part_hit_filter);
					
					break;

				case QueryPartLogic.Prohibited:
					if (primary_prohibited_part_query == null)
						primary_prohibited_part_query = new LNS.BooleanQuery ();
					primary_prohibited_part_query.Add (primary_part_query, LNS.BooleanClause.Occur.SHOULD);

					if (secondary_part_query != null) {
						if (secondary_prohibited_part_query == null)
							secondary_prohibited_part_query = new LNS.BooleanQuery ();
						secondary_prohibited_part_query.Add (secondary_part_query, LNS.BooleanClause.Occur.SHOULD);
					}

					if (part_hit_filter != null) {
						NotHitFilter nhf;
						nhf = new NotHitFilter (part_hit_filter);
						all_hit_filters.Add (new HitFilter (nhf.HitFilter));
					}

					break;
				}
			}

			return term_list;
		}