protected void Publish_Click(object sender, EventArgs e)
    {
        Util util = new Util();
        Hashtable State = (Hashtable)HttpRuntime.Cache[Session.SessionID];
        if (util.CheckSessionTimeout(State, Response, "../../Default.aspx")) return;

        //check if entries were set
        DB db = new DB();
        StringBuilder b_sql = new StringBuilder("SELECT * FROM applications ");
        b_sql.Append("WHERE application_name='" + State["SelectedApp"].ToString() + "'");
        b_sql.Append(" AND customer_id='" +  State["CustomerID"].ToString() + "'");
        DataRow[] rows = db.ViziAppsExecuteSql(State, b_sql.ToString());
        DataRow row = rows[0];
         if (row["production_app_name"] == DBNull.Value || row["production_app_name"].ToString().Length == 0)
         {
             PublishMessage.Text = "The Published App Name needs to be set and saved";
            return;
         }
         if (row["production_app_xml"] == DBNull.Value)
         {
             PublishMessage.Text = "The Publish Design needs to be saved";
            return;
         }

        string icon_url = util.GetApplicationLargeIcon(State,  State["ApplicationID"].ToString());
        if (icon_url == null || icon_url.Length == 0)
        {
            PublishMessage.Text = "The Icon image needs to be uploaded";
            return;
        }
        string splash_url = util.GetApplicationSplashImage(State,  State["ApplicationID"].ToString());
        if (splash_url == null || splash_url.Length == 0)
        {
            PublishMessage.Text = "The splash image needs to be uploaded";
            return;
        }

        //check on paid service
        //is payment current
        XmlUtil x_util = new XmlUtil();
        Hashtable features = util.IsProductionAppPaid(State);
        if (features == null)
        {
            PublishMessage.Text = "A production service needs to be paid for your app.";
            return;
        }
        else //check number of pages
        {
            int page_count = x_util.GetProductionAppPageCount(State);
            int sku_page_count = (int)features["max_pages"];
            if (page_count > sku_page_count)
            {
                PublishMessage.Text = "Your production app of " + page_count.ToString() + " pages exceeds the page limit of " + sku_page_count .ToString() + " for the production service you paid for.";
                return;
            }
        }

        State["UrlAccountIdentifier"] = util.GetUrlAccountIdentifier(State);
        if (State["UrlAccountIdentifier"].ToString().Length == 0)
        {
            PublishMessage.Text = "The Account Identifier has not been set. Go the Design Page and set the Account Identifier in the app properties";
            return;
        }

        WebAppsUtil web_util = new WebAppsUtil();
        AmazonS3 s3 = new AmazonS3();
        State["IsProduction"] = true;

        string file_name = State["SelectedApp"].ToString() + "/index.html";
        file_name = file_name.Replace(" ", "_");
        string save_file_path =  HttpRuntime.Cache["TempFilesPath"].ToString() + State["Username"].ToString() + "." + file_name.Replace("/index.html", ".html");

        if (File.Exists(save_file_path))
            File.Delete(save_file_path);

        string html = web_util.GetWebApp(State,util.GetStagingAppXml(State),1.0D,1.0D);
        File.WriteAllText(save_file_path, html);
         string key =  State["UrlAccountIdentifier"].ToString() + "/" + file_name;
        s3.UploadFileWithKey(State, file_name, save_file_path, key);

        if (File.Exists(save_file_path))
            File.Delete(save_file_path);

        string filename =  State["SelectedApp"].ToString().Replace(" ", "_") + "_qrcode.png";

        string url = "http://viziapps.s3-website-us-east-1.amazonaws.com/" +  State["UrlAccountIdentifier"].ToString() + "/" +  State["SelectedApp"].ToString().Replace(" ", "_");
        PublishMessage.Text = "Pulished App URL: " + url;

        BitlyData.LoginName = ConfigurationManager.AppSettings["BitlyLoginName"];
        BitlyData.APIKEY = ConfigurationManager.AppSettings["BitlyAPIKey"];
        String bitly_url = Bitly.ShortURL(url, Bitly.Format.TXT);
        QRCode.Src = Bitly.GetQRCodeURL(bitly_url);
        PublishedAppURL.Text = "Short-length published App URL: " + bitly_url;

        QRCode.Style.Value = "";
        QRCodeLabel.Style.Value = "";
        QRCodeLabel.Text = "QR Code for Published Web App: " + State["SelectedApp"].ToString() + ". Capture the URL from this image with any app that reads QR codes and you will see your app on your device in seconds.";
    }