docs: private Properties readHeaderRecord(boolean forward) throws IOException {
  		long fileSize = reader.length();
  		int headerSize;
  		int tailSize;
  		byte[] buffer;
  		long position;
  		if (forward) {
  			position = 0L;
  			headerSize = reader.readLength();
  			if (headerSize < 0 || fileSize < headerSize + 8) {
  				throw new IOException("Header size is incorrect");
  			}
  			buffer = new byte[headerSize];
  			reader.readFully(buffer, 0, headerSize);
  			tailSize = reader.readLength();
  		} else {
  			reader.seek(fileSize - 4);
  			tailSize = reader.readLength();
  			if (tailSize < 0 || fileSize < tailSize + 8) {
  				throw new IOException("Header size is incorrect");
  			}
  			position = fileSize - tailSize - 8L;
  			reader.seek(position);
  			headerSize = reader.readLength();
  			buffer = new byte[tailSize];
  			reader.readFully(buffer, 0, tailSize);
  		}
  		ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
  		for(LogRecordSerializer current: LogRepositoryBrowserImpl.KNOWN_FORMATTERS) {
  			try {
  				bais.reset();
  				DataInputStream input = new DataInputStream(bais);
  				if (LogRecordSerializer.HEADER == current.getType(input)) {
  					Properties result = current.deserializeFileHeader(input);
  					if (result != null) {
  						formatter = current;
  						if (headerSize != tailSize) {
  							logger.logp(Level.WARNING, className, "readHeaderRecord", "HPEL_InconsistencyInHeaderRecordSize",
  									new Object[]{Integer.toString(tailSize), Long.toString(position), Integer.toString(headerSize), file.getAbsolutePath()});
  						}
  						return result;
  					}
  				}
  			} catch (IOException ex) {
  				// Assume incorrect formatter.
  			}
  		}
  		throw new IOException("No formatter can read header record.");
  	}