int MinosTestImport::readTestFile( HANDLE ctfile )
{
   // read the stream as a sequence of Minos stanzas
   char rdbuffer[ IO_BUF_SIZE + 1 ];
   bool fileComplete = false;

   // NB - old versions might not have a proper header
   bool firstRead = true;
   std::string buffer;
   while ( !fileComplete )
   {
      DWORD chRead = 0;
      DWORD chToRead = IO_BUF_SIZE;
      bool ReadOK = ReadFile ( ctfile, rdbuffer, chToRead, &chRead, 0 );
      if ( ReadOK )
      {
         if ( chRead > 0 )
         {
            rdbuffer[ chRead ] = '\0';

            buffer += rdbuffer;
            if ( firstRead )
            {
               firstRead = false;
               iqOffset = 0;
               if ( strncmp( rdbuffer, header1, strlen( header1 ) ) == 0 )
               {
                  buffer = buffer.substr( strlen( header1 ), buffer.size() - strlen( header1 ) );  // overwriting what is there already
                  iqOffset = strlen( header1 );
               }
               else
                  if ( strncmp( rdbuffer, header2, strlen( header2 ) ) == 0 )
                  {
                     buffer = buffer.substr( strlen( header2 ), buffer.size() - strlen( header2 ) );  // overwriting what is there already
                     iqOffset = strlen( header2 );
                  }
               buffer = std::string( stubHeader ) + buffer;
            }
         }
         else
         {
            fileComplete = true;
         }

      }
      else
      {
         fileComplete = true;
      }
   }
   // and now we parse the document, and grind through the root
   buffer += "</stream:stream>";

   TiXmlBase::SetCondenseWhiteSpace( false );
   TiXmlDocument xdoc;
   xdoc.Parse( buffer.c_str(), 0 );
   TiXmlElement *tix = xdoc.RootElement();
   if ( !tix || !checkElementName( tix, "stream:stream" ) )
   {
      return 0;
   }
   int stanzas = 0;
   for ( TiXmlElement * e = tix->FirstChildElement(); e; e = e->NextSiblingElement() )
   {
      stanzas++;

      // Tiny gives us a "cursor" of row/column on the parsed data, but this
      // doesn't actually translate at all easily to a file position

      // I've added the code to get a data offset (DataPos)

      // as we get a position of the START rather than the END of a stanza,
      // we don't always get a good length, so we may need to do a "large" read in thos cases

      curfpos = iqOffset + e->DataPos() - 1 - strlen( stubHeader );
      analyseNode( this, e );
   }
   return stanzas;
}