docs: private ManageableCollection getCollectionByQuery(Class collectionClass, Class itemClass, Query query)
              throws ClassNotPersistenceCapableException, PersistenceBrokerException
      {
          if (log.isDebugEnabled()) log.debug("getCollectionByQuery (" + collectionClass + ", " + itemClass + ", " + query + ")");
  
          ClassDescriptor cld = pb.getClassDescriptor(itemClass);
          ManageableCollection result = null;
          OJBIterator iter = null;
          int fullSize = -1;
          int size = 0;
  
          final boolean isRetrievalTasksCreated = batchRetrieval && m_retrievalTasks == null;
          if (isRetrievalTasksCreated)
          {
              // Maps ReferenceDescriptors to HashSets of owners
              m_retrievalTasks = new HashMap();
          }
  
          // ==> enable materialization cache
          pb.getInternalCache().enableMaterializationCache();
          try
          {
              result = (ManageableCollection) collectionClass.newInstance();
              
              // now iterate over all elements and add them to the new collection
              // lifecycle events are disabled
              iter = pb.getIteratorFromQuery(query, cld);
              iter.disableLifeCycleEvents();
  
              // BRJ : get fullSizefor Query
              // to be removed when Query.fullSize is removed
              if (iter instanceof PagingIterator)
              {
                  fullSize = iter.fullSize();
              }
  
              while (iter.hasNext())
              {
                  Object candidate = iter.next();
  
                  /**
                   * MBAIRD
                   * candidate CAN be null in the case of materializing from an iterator based
                   * on a query for a class that is mapped to a table that has other classes
                   * mapped to that table as well, but aren't extents.
                   */
                  if (candidate != null)
                  {
                      IndirectionHandler handler = ProxyHelper.getIndirectionHandler(candidate);
  
                      if ((handler != null) || itemClass.isAssignableFrom(candidate.getClass()))
                      {
                          result.ojbAdd(candidate);
  
                          // BRJ: count added objects
                          // to be removed when Query.fullSize is removed
                          size++;
                      }
                      else
                      {
                          //warn the user
                          log.warn("Candidate object ["+candidate
                                      +"] class ["+candidate.getClass().getName()
                                      +"] is not a subtype of ["+itemClass.getName()
                                      +"] or any type of proxy. NOT INCLUDED in result collection");
                      }
                      if (prefetchProxies && (handler != null)
                              && (cld.getProxyPrefetchingLimit() > 0)
                              && addRetrievalTask(candidate, this))
                      {
                          new PBMaterializationListener(candidate, m_retrievalTasks,
                                  this, cld.getProxyPrefetchingLimit());
                      }
                  }
              }
  
              if (isRetrievalTasksCreated)
              {
                  // turn off auto prefetching for related proxies
                  final Class saveClassToPrefetch = classToPrefetch;
                  classToPrefetch = null;
                  try
                  {
                      performRetrievalTasks();
                  }
                  finally
                  {
                      classToPrefetch = saveClassToPrefetch;
                  }
              }
  
              // BRJ: fire LifeCycleEvents after execution of RetrievalTasks
              // to ensure objects are fully materialized
              Iterator resultIter = result.ojbIterator();
              while (resultIter.hasNext())
              {
                  Object obj = resultIter.next();
                  afterLookupEvent.setTarget(obj);
                  pb.fireBrokerEvent(afterLookupEvent);
                  afterLookupEvent.setTarget(null);
              }
  
              // ==> disable materialization cache
              pb.getInternalCache().disableMaterializationCache();
          }
          catch(RuntimeException e)
          {
              // ==> clear materialization cache
              pb.getInternalCache().doLocalClear();
              throw e;
          }
          catch (Exception ex)
          {
              // ==> clear materialization cache
              pb.getInternalCache().doLocalClear();
              log.error(ex);
              throw new PersistenceBrokerException(ex);
          }
          finally
          {
              if (iter != null)
              {
                  iter.releaseDbResources();
              }
              if (isRetrievalTasksCreated)
              {
                  m_retrievalTasks = null;
              }
          }
  
          // BRJ: store fullSize in Query to re-enable deprecated functionality
          // to be removed when Query.fullSize is removed
          if (fullSize < 0)
          {
              fullSize = size;	// use size of result
          }
          query.fullSize(fullSize);
          
          return result;
      }