/**
  * Return the query, resulting array may contain rubbish entries at the end. Assumes the caller
  * knows what it is doing!
  *
  * @param id read id
  * @param frame read frame
  * @return amino acid sequence
  * @exception IOException if an I/O error occurs.
  */
 byte[] query(final int id, final int frame) throws IOException {
   if (mQueryReader == null) {
     return EMPTY;
   } else if (mQueryReader.type() == SequenceType.DNA) {
     // In this situation, use precomputed array to store intermediate nt version
     final int length = mQueryReader.read(id, mWorkSpace);
     // Convert to protein in situ
     final Frame frames = ProteinOutputProcessor.FRAMES_MAPPING[frame + 3];
     final int limit = (length - Math.abs(frame) + 1) / 3;
     for (int j = 0, i = 0; j < limit; j++, i += 3) {
       mWorkSpaceProtein[j] = frames.code(mWorkSpace, length, i);
     }
     return mWorkSpaceProtein;
   } else {
     return mQueryReader.read(id);
   }
 }
 byte[] template(final int id) throws IOException {
   if (id != mCachedTemplateId) {
     if (mTemplateReader == null) {
       mCachedTemplate = EMPTY;
     } else {
       mCachedTemplate = mTemplateReader.read(id);
     }
     mCachedTemplateId = id;
   }
   return mCachedTemplate;
 }