public static string ShortenUrl(ShortenUrlServiceProvider provider, IEnumerable<string> words, string text, string username, string password, string apiKey)
        {
            if(provider.RequiresAuthentication(true) && (username.IsNullOrBlank() || password.IsNullOrBlank()))
            {
                throw new TweetSharpException("Expected credentials for the shortening service {0}".FormatWith(provider));
            }

            var hasAuth = provider.RequiresAuthentication(false) && (!username.IsNullOrBlank() && !password.IsNullOrBlank());
            var hasApiKey = provider.RequiresApiKey() && (!apiKey.IsNullOrBlank());
            var scheme = provider.GetScheme();

            switch (provider)
            {
                case ShortenUrlServiceProvider.Tomato:
                    text = ExecuteGet(text, words, "http://to.m8.to/api/shortenLink?url={0}");
                    break;
                case ShortenUrlServiceProvider.Trim:
                {
                    var result = text;
                    var function = new Func<string, string, string>((response, word) =>
                                                                    {
                                                                        var data = new {url = String.Empty};
                                                                        data = JsonConvert.DeserializeAnonymousType(response, data);
                                                                        
                                                                        if (!data.url.IsNullOrBlank())
                                                                        {
                                                                            result = result.Replace(word, data.url);
                                                                        }
                                                                        return result;
                                                                    });
                    text = hasApiKey
                               ? ExecuteGet(text, words, "http://tr.im/api/trim_url.json?api_key={0}&url={{0}}".FormatWith(apiKey), function)
                               : hasAuth
                                     ? ExecuteGet(text, words, "http://tr.im/api/trim_url.json?url={0}", function, username, password, scheme)
                                     : ExecuteGet(text, words, "http://tr.im/api/trim_url.json?url={0}", function);
                    break;
                }
                case ShortenUrlServiceProvider.Bitly:
               { 
                    /* {
                                "errorCode": 0, 
                                "errorMessage": "", 
                                "results": {
                                    "http://www.dimebrain.com": {
                                        "hash": "wzJq", 
                                        "shortKeywordUrl": "", 
                                        "shortUrl": "http://bit.ly/5Dch", 
                                        "userHash": "5Dch"
                                    }
                                }, 
                                "statusCode": "OK"
                           }*/

                    var result = text;
                    var function = new Func<string, string, string>((response, word) =>
                                                                    {
                                                                        response = response.Replace("\"", "");
                                                                        response = response.Replace(word, "");
                                                                        response = response.Replace(",", "");

                                                                        var url = word;
                                                                        foreach (var token in response.Split(' '))
                                                                        {
                                                                            if (!token.IsValidUrl())
                                                                            {
                                                                                continue;
                                                                            }

                                                                            url = token;
                                                                            break;
                                                                        }

                                                                        if (!url.IsNullOrBlank())
                                                                        {
                                                                            result = result.Replace(word, url);
                                                                        }

                                                                        return result;
                                                                    });

                    text = ExecuteGet(text, words,
                                      "http://api.bit.ly/shorten?version=2.0.1&longUrl={0}&login={1}&apiKey={2}",
                                      function, username, password, scheme);
                    break;
                }
                case ShortenUrlServiceProvider.IsGd:
                {
                    text = ExecuteGet(text, words, "http://is.gd/api.php?longurl={0}");
                    break;
                }
                case ShortenUrlServiceProvider.TinyUrl:
                {
                    text = ExecuteGet(text, words, "http://tinyurl.com/api-create.php?url={0}");
                    break;
                }
                default:
                    throw new TweetSharpException("Unknown service provider for URL shortening");
            }

            return text;
        }