@Override
	public void run()
	{
		if (threadPool.isShutdown() || threadPool.isTerminated())
		{
			return;
		}

		// Create random mail document
		final int senderID = Config.MIN_USER + generator.nextInt(Config.MAX_USER);
		final int receiverID = Config.MIN_USER + generator.nextInt(Config.MAX_USER);
		final MailType mailType = mailTypes[1 + generator.nextInt(mailTypes.length - 1)];
		final Mail mail;

		switch (mailType)
		{
			case USER:
			{
				final int textIndex = 1 + generator.nextInt(Config.SUBJECTS.length - 1);
				mail = new MailUser(senderID, receiverID, Config.SUBJECTS[textIndex], Config.BODIES[textIndex]);
				break;
			}
			case TRADE:
			{
				final ArrayList<Long> items = new ArrayList<>();
				final int itemCount = 1 + generator.nextInt(5);
				for (int i = 0; i < itemCount; ++i)
				{
					items.add(Math.abs(generator.nextLong()));
				}
				mail = new MailTrade(senderID, receiverID, items);
				break;
			}
			default:
				return;
		}

		// Put mail on storage queue
		requestController.addDocument(
				String.valueOf(receiverID),
				UUID.randomUUID().toString(),
				gson.toJson(mail),
				TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
		);

		if (!threadPool.isShutdown() && !threadPool.isTerminated())
		{
			threadPool.schedule(this, Config.CREATION_DELAY, Config.CREATION_TIMEUNIT);
		}
	}