@Override
	public UrlPair generateShortUrl(String longUrl) throws GenerateShortUrlFailureException {
		if (longUrl == null || longUrl.length() == 0) {
			throw new IllegalArgumentException("[generateShortUrl] longUrl is empty.");
		}

		/* If the UrlPair of the given longUrl has already existed, return it directly. */
		UrlPair existedUrlPair = findUrlPairByLongUrl(longUrl);
		if (existedUrlPair != null) {
			return existedUrlPair;
		}

		/* Check the algorithms availability. */
		Set<UrlShortenAlgorithm> algorithms = getUrlShortenAlgorithms();
		if (algorithms == null || algorithms.isEmpty()) {
			throw new GenerateShortUrlFailureException("[[generateShortUrl]] UrlShortenAlgorithms is empty.");
		}

		for (UrlShortenAlgorithm algorithm : algorithms) {
			String generatedShortUrl = algorithm.generateShortUrl(longUrl);

			/* Check generatedShortUrl exist or not */
			UrlPair checkUrlPair = findUrlPairByShortUrl(generatedShortUrl);
			if (checkUrlPair != null) {
				if (longUrl.equals(checkUrlPair.getLongUrl())) {
					return checkUrlPair;
				}
			} else {
				UrlPair newUrlPair = new UrlPair(generatedShortUrl, longUrl);
				try {
					persistUrlPair(newUrlPair);
					return newUrlPair;
				} catch (PersistUrlPairException e) {
					throw new GenerateShortUrlFailureException(e.getMessage(), e.getCause());
				}
			}
		}

		/* All possible generated urlPair have already existed, throw a failure exception */
		GenerateShortUrlFailureException ex = new GenerateShortUrlFailureException();
		ex.setLongUrl(longUrl);
		throw ex;
	}