/// <summary>
        /// Request a generic resource from the service server(s).
        /// </summary>
        /// <param name="route">
        /// The API route to make the request to.
        /// </param>
        /// <param name="responseReceived">
        /// Gets set to false if no response was received, otherwise false.
        /// </param>
        /// <param name="noLogging">
        /// Whether or not to log errors. Since HttpWebRequest brilliant throws exceptions for
        /// non-success HTTP status codes, it's nice to be able to control whether or not your
        /// request should have errors logged.
        /// </param>
        /// <returns>
        /// A non-null byte array on success. Null byte array on failure.
        /// </returns>
        public byte[] RequestResource(ServiceResource resource, out HttpStatusCode code, out bool responseReceived, Dictionary <string, string> parameters = null, bool noLogging = false)
        {
            responseReceived = true;

            try
            {
                // Try to send the device name as well. Helps distinguish between clients under the
                // same account.
                string deviceName = string.Empty;

                try
                {
                    deviceName = Environment.MachineName;
                }
                catch
                {
                    deviceName = "Unknown";
                }

                var request = GetApiBaseRequest(m_namedResourceMap[resource]);

                var accessToken = AuthToken;

                //m_logger.Info("RequestResource1: accessToken=" + accessToken);
                m_logger.Info("RequestResource: accessToken length={0}", accessToken == null ? "(null)" : accessToken.Length.ToString());
                m_logger.Info("RequestResource: {0}", resource.ToString());

                if (StringExtensions.Valid(accessToken))
                {
                    request.Headers.Add("Authorization", string.Format("Bearer {0}", accessToken));
                }
                else if (resource != ServiceResource.RetrieveToken)
                {
                    m_logger.Info("RequestResource1: Authorization failed.");
                    AuthTokenRejected?.Invoke();
                    code = HttpStatusCode.Unauthorized;
                    return(null);
                }

                System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
                string version = System.Reflection.AssemblyName.GetAssemblyName(assembly.Location).Version.ToString();

                // Build out post data with username and identifier.
                string postString = string.Format("&identifier={0}&device_id={1}", FingerPrint.Value, Uri.EscapeDataString(deviceName));

                if (parameters != null)
                {
                    foreach (var parameter in parameters)
                    {
                        postString += $"&{parameter.Key}={parameter.Value}";
                    }
                }

                if (resource == ServiceResource.UserDataSumCheck)
                {
                    postString += string.Format("&app_version={0}", version);
                }

                var formData = System.Text.Encoding.UTF8.GetBytes(postString);

                // Don't forget to the set the content length to the total length of our form POST data!
                request.ContentLength = formData.Length;

                // Grab the request stream so we can POST our login form data to it.
                using (var requestStream = request.GetRequestStream())
                {
                    // Write and close.
                    requestStream.Write(formData, 0, formData.Length);
                    requestStream.Close();
                }

                // Now that our login form data has been POST'ed, get a response.
                using (var response = (HttpWebResponse)request.GetResponse())
                {
                    // Get the response code as an int so we can range check it.
                    var intCode = (int)response.StatusCode;

                    code = (HttpStatusCode)intCode;

                    try
                    {
                        // Check if response code is considered a success code.
                        if (intCode >= 200 && intCode <= 299)
                        {
                            using (var memoryStream = new MemoryStream())
                            {
                                response.GetResponseStream().CopyTo(memoryStream);

                                // We do this just in case we get something like a 204. The idea here
                                // is that if we return a non-null, the call was a success.
                                var responseBody = memoryStream.ToArray();
                                if (responseBody == null || intCode == 204)
                                {
                                    return(null);
                                }

                                return(responseBody);
                            }
                        }
                        else
                        {
                            m_logger.Info("When requesting resource, got unexpected response code of {0}.", code);
                        }
                    }
                    finally
                    {
                        response.Close();
                        request.Abort();
                    }
                }
            }
            catch (WebException e)
            {
                // KF - Set this to 0 for default. 0's a pretty good indicator of no internet.
                code = 0;

                try
                {
                    using (WebResponse response = e.Response)
                    {
                        if (response == null)
                        {
                            responseReceived = false;
                        }

                        HttpWebResponse httpResponse = (HttpWebResponse)response;
                        m_logger.Error("Error code: {0}", httpResponse.StatusCode);

                        int intCode = (int)httpResponse.StatusCode;

                        code = (HttpStatusCode)intCode;

                        // Auth failure means re-log EXCEPT when requesting deactivation.
                        if ((intCode == 401 || intCode == 403) && resource != ServiceResource.DeactivationRequest)
                        {
                            AuthToken = string.Empty;
                            m_logger.Info("RequestResource2: Authorization failed.");
                            AuthTokenRejected?.Invoke();
                        }
                        else if (intCode > 399 && intCode <= 499 && resource != ServiceResource.DeactivationRequest)
                        {
                            m_logger.Info("Error occurred in RequestResource: {0}", intCode);
                        }

                        using (Stream data = response.GetResponseStream())
                            using (var reader = new StreamReader(data))
                            {
                                string text = reader.ReadToEnd();
                                m_logger.Error(text);
                            }
                    }
                }
                catch { }

                if (noLogging == false)
                {
                    m_logger.Error(e.Message);
                    m_logger.Error(e.StackTrace);
                }
            }
            catch (Exception e)
            {
                // XXX TODO - Good default?
                code = HttpStatusCode.InternalServerError;

                if (noLogging == false)
                {
                    while (e != null)
                    {
                        m_logger.Error(e.Message);
                        m_logger.Error(e.StackTrace);
                        e = e.InnerException;
                    }
                }
            }



            return(null);
        }