class MessageArchive implements AutoCloseable {

	public List<Message> messageQuery(long from, long to) {
		LoggingService.logDebug(MODULE_NAME, "Start message query");
		boolean outOfMemory = false;
		List<Message> result = new ArrayList<>();
		
		File workingDirectory = new File(diskDirectory);
		FilenameFilter filter = (dir, fileName) -> fileName.substring(0, name.length()).equals(name)
				&& fileName.substring(fileName.indexOf(".")).equals(".idx");
		File[] listOfFiles = workingDirectory.listFiles(filter);
		Stack<File> resultSet = new Stack<>();
		if (listOfFiles != null) {
			Arrays.sort(listOfFiles);

			int i = listOfFiles.length - 1;
			for (; i >= 0; i--) {
				File file = listOfFiles[i];
				if (!file.isFile())
					continue;
				long timestamp = Long.parseLong(file.getName().substring(name.length() + 1, file.getName().indexOf(".")));
				if (timestamp < from)
					break;
				if (timestamp >= from && timestamp <= to)
					resultSet.push(file);
			}
			if (i >= 0)
				resultSet.push(listOfFiles[i]);
		}
		
		byte[] header = new byte[HEADER_SIZE];
		while (!resultSet.isEmpty() && !outOfMemory) {
			File file = resultSet.pop();
			String fileName = file.getName();
			String dataFileName = diskDirectory + fileName.substring(0, fileName.indexOf(".")) + ".iomsg";
			try (RandomAccessFile indexFile = new RandomAccessFile(new File(diskDirectory + fileName), "r");
				RandomAccessFile dataFile = new RandomAccessFile(new File(dataFileName), "r")){
				long dataFileLength = dataFile.length();
				while (indexFile.getFilePointer() < indexFile.length()) {
					if (freeMemory() < 32 * Constants.MiB) {
						outOfMemory = true;
						break;
					}

					indexFile.read(header, 0, HEADER_SIZE);
					if (((header[0] * 256) + header[1]) != 4)
						throw new Exception("invalid index file format");
					long dataPos = indexFile.readLong();
					int dataSize = getDataSize(header);
					if (dataPos + dataSize > dataFileLength || dataSize > dataFileLength)
						throw new Exception("invalid data file format");
					byte[] data = new byte[dataSize];
					dataFile.read(data, 0, dataSize);
					Message message = new Message(header, data);
					if (message.getTimestamp() < from || message.getTimestamp() > to)
						continue;
					result.add(message);
				}
			} catch (Exception e) {
				LoggingService.logError("Message Archive", e.getMessage(), e);
			}
		}
		LoggingService.logDebug(MODULE_NAME, "Finish message query");
		return result;
	}

	public  MessageArchive(String name);

}