public synchronized final void close() {
		if (!open) {
			return; // it is not an error to attempt to close a closed Query
		}
		if (Prolog.thread_self() == -1) {
			throw new JPLException("no engine is attached to this thread");
		}
		if (Prolog.current_engine().value != engine.value) {
			throw new JPLException("this Query's engine is not that which is attached to this thread");
		}
		Query topmost = m.get(new Long(engine.value));
		if (topmost != this) {
			throw new JPLException("this Query (" + this.hashCode() + ":" + this.toString() + ") is not topmost (" + topmost.hashCode() + ":" + topmost.toString() + ") within its engine["
					+ engine.value + "]");
		}
		Prolog.close_query(qid);
		qid = null; // for tidiness
		org.jpl7.fli.Prolog.discard_foreign_frame(fid);
		fid = null; // for tidiness
		m.remove(new Long(engine.value));
		if (subQuery == null) { // only Query open in this engine?
			if (Prolog.current_engine_is_pool()) { // this (Query's) engine is from the pool?
				Prolog.release_pool_engine();
				// System.out.println("JPL releasing engine[" + engine.value + "]");
			} else {
				// System.out.println("JPL   leaving engine[" + engine.value + "]");
			}
		} else {
			m.put(new Long(engine.value), subQuery);
			// System.out.println("JPL retaining engine[" + engine.value + "] popping subQuery(" + subQuery.hashCode() + ":" + subQuery.toString() + ")");
		}
		open = false; // this Query is now closed
		engine = null; // this Query, being closed, is no longer associated with any Prolog engine
		subQuery = null; // this Query, being closed, is not stacked upon any other Query
	}