public function parseURL( $url ) {
		// Feeding fully encoded URLs will not work.  So let's detect and decode if needed first.
		// This is just idiot proofing.
		// See if the URL is fully encoded by checking if the :// is encoded.
		// This prevents URLs where double encoded values aren't mistakenly decoded breaking the URL.
		if ( preg_match( '/^([a-z0-9\+\-\.]*)(?:%3A%2F%2F|%3A\/\/|:%2F%2F)/i', $url ) ) {
			// First let's break the fragment out to prevent accidentally mistaking a decoded %23 as a #
			$fragment = parse_url( $url, PHP_URL_FRAGMENT );
			if ( !is_null( $fragment ) ) {
				$url = strstr( $url, "#", true );
			}
			// Decode URL
			$url = rawurldecode( $url );
			// Re-encode the remaining #'s
			$url = str_replace( "#", "%23", $url );
			// Reattach the fragment
			if ( !is_null( $fragment ) ) {
				$url .= "#$fragment";
			}
		}
		// Sometimes the scheme is followed by a single slash instead of a double.
		// Web browsers and archives support this, so we should too.
		if ( preg_match( '/^([a-z0-9\+\-\.]*:)?\/([^\/].+)/i', $url, $match ) ) {
			$url = $match[1] . "//" . $match[2];
		}
		// Sometimes protocol relative URLs are not formatted correctly
		// This checks to see if the URL starts with :/ or ://
		// We will assume http in these cases
		if ( preg_match( '/^:\/\/?([^\/].+)/i', $url, $match ) ) {
			$url = "http://" . $match[1];
		}
		// If we're missing the scheme and double slashes entirely, assume http.
		// The parse_url function fails without this
		if ( !preg_match( '/(?:[a-z0-9\+\-\.]*:)?\/\//i', $url ) ) {
			$url = "http://" . $url;
		}
		$encodedUrl = preg_replace_callback(
			'%[^:/@?&=#;]+%sD',
			function ( $matches ) {
				return urlencode( $matches[0] );
			},
			$url
		);
		$parts = parse_url( $encodedUrl );
		// Check if the URL was actually parsed.
		if ( $parts !== false ) {
			foreach ( $parts as $name => $value ) {
				$parts[$name] = urldecode( $value );
			}
		}

		return $parts;
	}