public static function normalizeIPv6($address) {
		$normalizedAddress = '';
		$stageOneAddress = '';

			// according to RFC lowercase-representation is recommended
		$address = strtolower($address);

			// normalized representation has 39 characters (0000:0000:0000:0000:0000:0000:0000:0000)
		if (strlen($address) == 39) {
				// already in full expanded form
			return $address;
		}

		$chunks = explode('::', $address); // Count 2 if if address has hidden zero blocks
		if (count($chunks) == 2) {
			$chunksLeft = explode(':', $chunks[0]);
			$chunksRight = explode(':', $chunks[1]);
			$left = count($chunksLeft);
			$right = count($chunksRight);

				// Special case: leading zero-only blocks count to 1, should be 0
			if ($left == 1 && strlen($chunksLeft[0]) == 0) {
				$left = 0;
			}

			$hiddenBlocks = 8 - ($left + $right);
			$hiddenPart = '';
			$h = 0;
			while ($h < $hiddenBlocks) {
				$hiddenPart .= '0000:';
				$h++;
			}

			if ($left == 0) {
				$stageOneAddress = $hiddenPart . $chunks[1];
			} else {
				$stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1];
			}
		} else {
			$stageOneAddress = $address;
		}

			// normalize the blocks:
		$blocks = explode(':', $stageOneAddress);
		$divCounter = 0;
		foreach ($blocks as $block) {
			$tmpBlock = '';
			$i = 0;
			$hiddenZeros = 4 - strlen($block);
			while ($i < $hiddenZeros) {
				$tmpBlock .= '0';
				$i++;
			}
			$normalizedAddress .= $tmpBlock . $block;
			if ($divCounter < 7) {
				$normalizedAddress .= ':';
				$divCounter++;
			}
		}
		return $normalizedAddress;
	}