/// <summary>
        /// Ensures that the given shard map name is valid.
        /// </summary>
        /// <param name="shardMapName">Input shard map name.</param>
        private static void ValidateShardMapName(string shardMapName)
        {
            ExceptionUtils.DisallowNullOrEmptyStringArgument(shardMapName, "shardMapName");

            // Disallow non-alpha-numeric characters.
            foreach (char c in shardMapName)
            {
                if (!Char.IsLetter(c) && !Char.IsNumber(c) && !Char.IsPunctuation(c))
                {
                    throw new ArgumentException(
                              StringUtils.FormatInvariant(
                                  Errors._ShardMapManager_UnsupportedShardMapName,
                                  shardMapName),
                              "shardMapName");
                }
            }

            // Ensure that length is within bounds.
            if (shardMapName.Length > GlobalConstants.MaximumShardMapNameLength)
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._ShardMapManager_UnsupportedShardMapNameLength,
                              shardMapName,
                              GlobalConstants.MaximumShardMapNameLength),
                          "shardMapName");
            }
        }
        /// <summary>
        /// Constructor that allows specification of protocol, address, port and database to identify a shard.
        /// </summary>
        /// <param name="server">Fully qualified hostname of the server for the shard database.</param>
        /// <param name="database">Name of the shard database.</param>
        /// <param name="protocol">Transport protcol used for the connection.</param>
        /// <param name="port">Port number for TCP/IP connections. Specify 0 to use the default port for the specified <paramref name="protocol"/>.</param>
        public ShardLocation(
            string server,
            string database,
            SqlProtocol protocol,
            int port)
        {
            if (protocol < SqlProtocol.Default || protocol > SqlProtocol.SharedMemory)
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._ShardLocation_UnsupportedProtocol,
                              protocol),
                          "protocol");
            }

            if (port < 0 || 65535 < port)
            {
                throw new ArgumentOutOfRangeException(
                          "port",
                          StringUtils.FormatInvariant(
                              Errors._ShardLocation_InvalidPort,
                              port));
            }

            ExceptionUtils.DisallowNullOrEmptyStringArgument(server, "server");
            ExceptionUtils.DisallowNullOrEmptyStringArgument(database, "database");

            if (server.Length > GlobalConstants.MaximumServerLength)
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._ShardLocation_InvalidServerOrDatabase,
                              "Server",
                              GlobalConstants.MaximumServerLength),
                          "server");
            }

            if (database.Length > GlobalConstants.MaximumDatabaseLength)
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._ShardLocation_InvalidServerOrDatabase,
                              "Database",
                              GlobalConstants.MaximumDatabaseLength),
                          "database");
            }

            this.Protocol = protocol;
            this.Server   = server;
            this.Port     = port;
            this.Database = database;
            _hashCode     = this.CalculateHashCode();
        }