storage_uri generate_queue_uri(const cloud_queue_client& service_client, const cloud_queue& queue)
    {
        web::http::uri primary_uri = generate_queue_uri(service_client.base_uri().primary_uri(), queue);
        web::http::uri secondary_uri = generate_queue_uri(service_client.base_uri().secondary_uri(), queue);

        return storage_uri(primary_uri, secondary_uri);
    }
    storage_uri generate_queue_uri(const cloud_queue_client& service_client, const utility::string_t& prefix, bool get_metadata, int max_results, const continuation_token& continuation_token)
    {
        web::http::uri primary_uri = generate_queue_uri(service_client.base_uri().primary_uri(), prefix, get_metadata, max_results, continuation_token);
        web::http::uri secondary_uri = generate_queue_uri(service_client.base_uri().secondary_uri(), prefix, get_metadata, max_results, continuation_token);

        return storage_uri(primary_uri, secondary_uri);
    }
    storage_uri generate_queue_message_uri(const cloud_queue_client& service_client, const cloud_queue& queue, const cloud_queue_message& message)
    {
        web::http::uri primary_uri(generate_queue_message_uri(service_client.base_uri().primary_uri(), queue, message));
        web::http::uri secondary_uri(generate_queue_message_uri(service_client.base_uri().secondary_uri(), queue, message));

        return storage_uri(std::move(primary_uri), std::move(secondary_uri));
    }
    storage_uri construct_default_endpoint(const utility::string_t& scheme, const utility::string_t& account_name, const utility::string_t& hostname_prefix, const utility::string_t& endpoint_suffix)
    {
        utility::ostringstream_t primary;
        primary << scheme << U("://") << account_name << U('.') << hostname_prefix << U('.') << endpoint_suffix;

        utility::ostringstream_t secondary;
        secondary << scheme << U("://") << account_name << secondary_location_account_suffix << U('.') << hostname_prefix << U('.') << endpoint_suffix;

        return storage_uri(web::http::uri(primary.str()), web::http::uri(secondary.str()));
    }
    cloud_storage_account cloud_storage_account::get_development_storage_account(const web::http::uri& proxy_uri)
    {
        web::http::uri_builder builder;
        if (!proxy_uri.is_empty())
        {
            builder.set_scheme(proxy_uri.scheme());
            builder.set_host(proxy_uri.host());
        }
        else
        {
            builder.set_scheme(U("http"));
            builder.set_host(U("127.0.0.1"));
        }

        builder.set_path(devstore_account_name);

        builder.set_port(10000);
        auto blob_endpoint = storage_uri(builder.to_uri());

        builder.set_port(10001);
        auto queue_endpoint = storage_uri(builder.to_uri());

        builder.set_port(10002);
        auto table_endpoint = storage_uri(builder.to_uri());

        auto credentials = storage_credentials(devstore_account_name, devstore_account_key);
        auto account = cloud_storage_account(credentials, blob_endpoint, queue_endpoint, table_endpoint);
        
        account.m_is_development_storage_account = true;
        account.m_settings.insert(std::make_pair(use_development_storage_setting_string, use_development_storage_setting_value));
        if (!proxy_uri.is_empty())
        {
            account.m_settings.insert(std::make_pair(development_storage_proxy_uri_setting_string, proxy_uri.to_string()));
        }
        
        return account;
    }
    cloud_storage_account cloud_storage_account::parse_explicit_settings(std::map<utility::string_t, utility::string_t> settings)
    {
        utility::string_t blob_endpoint;
        utility::string_t queue_endpoint;
        utility::string_t table_endpoint;
        get_setting(settings, blob_endpoint_setting_string, blob_endpoint);
        get_setting(settings, queue_endpoint_setting_string, queue_endpoint);
        get_setting(settings, table_endpoint_setting_string, table_endpoint);
        storage_credentials credentials(get_credentials(settings));
        
        if (settings.empty() && (!blob_endpoint.empty() || !queue_endpoint.empty() || !table_endpoint.empty()))
        {
            return cloud_storage_account(credentials,
                blob_endpoint.empty() ? storage_uri() : storage_uri(web::http::uri(blob_endpoint)),
                queue_endpoint.empty() ? storage_uri() : storage_uri(web::http::uri(queue_endpoint)),
                table_endpoint.empty() ? storage_uri() : storage_uri(web::http::uri(table_endpoint)));
        }

        return cloud_storage_account();
    }
    cloud_storage_account cloud_storage_account::parse_defaults_settings(std::map<utility::string_t, utility::string_t> settings)
    {
        utility::string_t scheme;
        utility::string_t account_name;
        utility::string_t account_key;

        if (get_setting(settings, default_endpoints_protocol_setting_string, scheme) &&
            get_setting(settings, account_name_setting_string, account_name) &&
            get_setting(settings, account_key_setting_string, account_key))
        {
            utility::string_t endpoint_suffix;
            if (!get_setting(settings, endpoint_suffix_setting_string, endpoint_suffix))
            {
                endpoint_suffix = default_endpoint_suffix;
            }

            utility::string_t blob_endpoint;
            utility::string_t queue_endpoint;
            utility::string_t table_endpoint;
            get_setting(settings, blob_endpoint_setting_string, blob_endpoint);
            get_setting(settings, queue_endpoint_setting_string, queue_endpoint);
            get_setting(settings, table_endpoint_setting_string, table_endpoint);

            if (settings.empty())
            {
                cloud_storage_account account(storage_credentials(account_name, account_key),
                    blob_endpoint.empty() ? construct_default_endpoint(scheme, account_name, default_blob_hostname_prefix, endpoint_suffix) : storage_uri(web::http::uri(blob_endpoint)),
                    queue_endpoint.empty() ? construct_default_endpoint(scheme, account_name, default_queue_hostname_prefix, endpoint_suffix) : storage_uri(web::http::uri(queue_endpoint)),
                    table_endpoint.empty() ? construct_default_endpoint(scheme, account_name, default_table_hostname_prefix, endpoint_suffix) : storage_uri(web::http::uri(table_endpoint)));

                account.m_endpoint_suffix = endpoint_suffix;
                return account;
            }
        }

        return cloud_storage_account();
    }