/// <summary>
        /// Add links of a decrypted container to Download Station
        /// </summary>
        /// <param name="decrypter">ContainerDecrypter</param>
        /// <returns>Success?</returns>
        public static bool AddLinksToDownloadStation(DecrypterBase decrypter)
        {
            try
            {
                if (!decrypter.IsDecypted)
                {
                    decrypter.Decrypt();
                }

                return Adapter.AddLinksToDownloadStation(decrypter.Links.ToList());
            }
            catch (Exception ex)
            {
                Adapter.ShowBalloonTip(ex.Message, ToolTipIcon.Error);
            }

            return false;
        }
        /// <remarks>
        /// Based on code created by bennyborn
        /// https://github.com/bennyborn/ClickNLoadDecrypt/
        /// </remarks>
        private static void WebRequestCallback(IAsyncResult result)
        {
            HttpListenerContext context = _httpListener.EndGetContext(result);
            _httpListener.BeginGetContext(new AsyncCallback(WebRequestCallback), _httpListener);
            DecrypterBase decrypter = null;
            byte[] responseBuffer = new byte[0];

            // build response data
            HttpListenerResponse response = context.Response;
            string responseString = "";
            response.StatusCode = 200;

            if (context.Request.HttpMethod.ToUpper() == "HEAD")
            {
                response.Close();
            }
            else
            {
                response.Headers.Add("Content-Type: text/html");
                // crossdomain.xml
                if (context.Request.RawUrl == "/crossdomain.xml")
                {
                    responseString = "<?xml version=\"1.0\"?>"
                    + "<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">"
                    + "<cross-domain-policy>"
                    + "<allow-access-from domain=\"*\" />"
                    + "</cross-domain-policy>";
                }
                else if (context.Request.RawUrl == "/jdcheck.js")
                {
                    responseString = "jdownloader=true; var version='18507';";
                }
                else if (context.Request.RawUrl.StartsWith("/flash"))
                {
                    if (context.Request.RawUrl.Contains("addcrypted2"))
                    {
                        System.IO.Stream body = context.Request.InputStream;
                        System.IO.StreamReader reader = new System.IO.StreamReader(body, context.Request.ContentEncoding);
                        String requestBody = System.Web.HttpUtility.UrlDecode(reader.ReadToEnd());

                        if (!string.IsNullOrEmpty(requestBody))
                        {
                            decrypter = new ClickNLoadDecrypter(requestBody);
                        }

                        responseString = "success\r\n";
                    }
                    else
                    {
                        System.IO.Stream body = context.Request.InputStream;
                        System.IO.StreamReader reader = new System.IO.StreamReader(body, context.Request.ContentEncoding);
                        String requestBody = System.Web.HttpUtility.UrlDecode(reader.ReadToEnd());

                        if (!string.IsNullOrEmpty(requestBody))
                        {
                            decrypter = new PlainClickNLoadDecrypter(requestBody);
                        }

                        responseString = "success\r\n";
                    }
                }
                else if (context.Request.RawUrl.StartsWith("/OpenFile?"))
                {
                    string filePath = System.Web.HttpUtility.UrlDecode(context.Request.RawUrl.Substring(10));

                    if (!string.IsNullOrEmpty(filePath))
                    {
                        if (Adapter.FILE_TYPES_NO_DECRYPT.Contains(Path.GetExtension(filePath).ToLower()))
                        {
                            new Task(() => { Adapter.AddFileToDownloadStation(filePath); }).Start();   
                        }
                        else
                        {
                            try
                            {
                                decrypter = new ContainerDecrypter.DcryptItDecrypter(filePath);
                            }
                            catch (ArgumentException ex)
                            {
                                Adapter.ShowBalloonTip(ex.Message, ToolTipIcon.Warning);
                            }
                        }
                    }

                    responseString = "success\r\n";
                }
                else if (context.Request.RawUrl.StartsWith("/DownloadFile?"))
                {
                    string id = System.Web.HttpUtility.UrlDecode(context.Request.RawUrl.Substring(14));

                    try
                    {
                        if (_fileDownloads.ContainsKey(id))
                        {
                            string path = _fileDownloads[id];
                            _fileDownloads.Remove(id);

                            responseBuffer = File.ReadAllBytes(path);

                            response.Headers.Remove("Content-Type");

                            response.Headers.Add("Content-Type: application/octet-stream");
                            response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(path));
                        }
                        else
                        {
                            response.StatusCode = 404;
                        }
                    }
                    catch (Exception ex)
                    {
                        response.StatusCode = 500;

                        Adapter.ShowBalloonTip(ex.Message, ToolTipIcon.Error);
                    }                    
                }
                else
                {
                    response.StatusCode = 400;
                }

                if (!string.IsNullOrEmpty(responseString))
                {
                    responseBuffer = System.Text.Encoding.UTF8.GetBytes(responseString);
                }

                response.ContentLength64 = responseBuffer.Length;

                // output response
                System.IO.Stream output = response.OutputStream;
                output.Write(responseBuffer, 0, responseBuffer.Length);
                output.Close();

                if (decrypter != null)
                {
                    try
                    {
                        decrypter.Decrypt();
                    }
                    catch (Exception ex)
                    {
                        Adapter.ShowBalloonTip(ex.Message, ToolTipIcon.Error);
                    }          

                    if (Properties.Settings.Default.ShowDecryptedLinks)
                    {
                        frmSettings.Instance.Invoke((MethodInvoker)(() =>
                        {
                            // Run on UI thread
                            frmAddLinks.ShowInstance(decrypter.Links);
                        }
                        ));
                    }
                    else
                    {
                        Adapter.AddLinksToDownloadStation(decrypter);
                    }
                }
            }
        }