private bool Create()
        {
            //m_created_ts = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
            m_created_ts = 0;

            if (m_original_currency_code == "BTC") {
                m_btc_amount = m_original_amount;
            } else {
                m_btc_amount = ToBTC(m_original_amount, m_original_currency_code);
            }

            BitcoinAddress addr = new BitcoinAddress(m_connectionString, m_config);
            m_btc_address = addr.AddressForAvatar(m_payee, m_payee_email);
            if (m_btc_address == "") {
                return false;
            }
            //m_btc_address = "15S5AqChfugJRaUZSAe2tkvhjqMkn3qo7y";

            string query = "";
            query += "INSERT INTO opensim_btc_transactions (";
            query += "payee, ";
            query += "item_name, ";
            query += "transaction_code, ";
            query += "original_amount, ";
            query += "original_currency_code, ";
            query += "btc_amount, ";
            query += "notify_url, ";
            query += "btc_address, ";
            query += "num_confirmations_required, ";
            query += "created_ts";
            query += ") values(";
            query += "?payee, ";
            query += "?item_name, ";
            query += "?transaction_code, ";
            query += "?original_amount, ";
            query += "?original_currency_code, ";
            query += "?btc_amount, ";
            query += "?notify_url, ";
            query += "?btc_address, ";
            query += "?num_confirmations_required, ";
            query += "?created_ts);";

            using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
            {

                dbcon.Open();

                MySqlCommand cmd = new MySqlCommand( query, dbcon);

                try
                {
                    using (cmd)
                    {
                        cmd.Parameters.AddWithValue("?payee", m_payee);
                        cmd.Parameters.AddWithValue("?item_name", m_item_name);
                        cmd.Parameters.AddWithValue("?transaction_code", m_transaction_code);
                        cmd.Parameters.AddWithValue("?original_amount", m_original_amount);
                        cmd.Parameters.AddWithValue("?original_currency_code", m_original_currency_code);
                        cmd.Parameters.AddWithValue("?btc_amount", m_btc_amount);
                        cmd.Parameters.AddWithValue("?notify_url", m_notify_url);
                        cmd.Parameters.AddWithValue("?btc_address", m_btc_address);
                        cmd.Parameters.AddWithValue("?num_confirmations_required", m_num_confirmations_required);
                        cmd.Parameters.AddWithValue("?created_ts", m_created_ts);
                        cmd.ExecuteNonQuery();
                        cmd.Dispose();

                        return true;

                    }
                }
                catch (Exception)
                {
                    //m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
                }

            }

            return false;
        }
        //public Hashtable HandleBitcoinRegistrationRequest(Dictionary<string, object> getvals, Dictionary<string,object> postvals)
        public Hashtable HandleBitcoinRegistrationRequest(Hashtable request_hash)
        {
            Dictionary<string, object> postvals = ServerUtils.ParseQueryString ((string)request_hash["body"]);

            //string base_url = "http://beech/TODO";

            string base_url = m_scenes[0].RegionInfo.ExternalHostName + ":" + m_scenes[0].RegionInfo.HttpPort;
            bool has_errors = false;

            string btc_session_id = "";
            if (postvals.ContainsKey("btc_session_id")) {
                btc_session_id = (string)postvals["btc_session_id"];
            } else if (request_hash.ContainsKey("btc_session_id")) {
                btc_session_id = (string)request_hash["btc_session_id"];
            }

            //Console.WriteLine("btc session id is "+btc_session_id);

            if (btc_session_id == "") {
                has_errors = true;
            }

            string user_identifier = "";
            UUID session_uuid = new UUID (btc_session_id);
            if (m_sessionkeyuser.ContainsKey(session_uuid)) {
                user_identifier = m_sessionkeyuser[session_uuid].ToString();
                if (user_identifier == "") {
                    has_errors = true;
                }
            } else {
                has_errors = true;
            }

            bool is_submit = false;

            List<string> addresses_created = new List<string>();
            List<string> addresses_failed = new List<string>();

            if (postvals.ContainsKey("addresses")) {

                is_submit = true;
                string address_text = (string)postvals["addresses"];

                string[] addresses = Regex.Split(address_text, "/\n/");

                for (int i=0; i<addresses.Length; i++) {
                    BitcoinAddress btc_addr = new BitcoinAddress(m_connectionString, m_btcconfig);
                    if (btc_addr.Create(user_identifier, addresses[i])) {
                        addresses_created.Add(addresses[i]);
                    } else {
                        addresses_failed.Add(addresses[i]);
                    }
                }

            }

            BitcoinAddress count_btc_addr = new BitcoinAddress(m_connectionString, m_btcconfig);
            int count_all_addresses = count_btc_addr.CountAddressesForAvatar(user_identifier, true);
            int count_usable_addresses = count_btc_addr.CountAddressesForAvatar(user_identifier, false);

            Dictionary<string, string> replacements = new Dictionary<string, string> ();
            //replacements.Add ("{BTC_SESSION_ID}",  HttpUtility.HtmlEncode(btc_session_id));
            //TODO put HttpUtility back
            replacements.Add ("{BTC_SESSION_ID}", btc_session_id);
            if (is_submit) {
                replacements.Add ("{BTC_DISABLE_COMPLETE_START}",  "<!--");
                replacements.Add ("{BTC_DISABLE_COMPLETE_END}",  "-->");
                replacements.Add ("{BTC_DISABLE_INCOMPLETE_START}",  "");
                replacements.Add ("{BTC_DISABLE_INCOMPLETE_END}",  "");
            } else {
                replacements.Add ("{BTC_DISABLE_INCOMPLETE_START}",  "<!--");
                replacements.Add ("{BTC_DISABLE_INCOMPLETE_END}",  "-->");
                replacements.Add ("{BTC_DISABLE_COMPLETE_START}",  "");
                replacements.Add ("{BTC_DISABLE_COMPLETE_END}",  "");
            }
            replacements.Add ("{BTC_COUNT_NEW_ADDRESSES}", addresses_created.Count.ToString());
            replacements.Add ("{BTC_COUNT_ALL_ADDRESSES}",  count_all_addresses.ToString());
            replacements.Add ("{BTC_COUNT_USABLE_ADDRESSES}", count_usable_addresses.ToString());

            string template;

            try {
                template = File.ReadAllText ("bitcoin-register-template.htm");
            } catch (IOException) {
                template = "Error: bitcoin-register-template.htm does not exist.";
                //m_log.Error ("[FreeMoney] Unable to load template file.");
                m_log.Error("Could not load template file bitcoin-register-template.htm");
                has_errors = true;
            }

            int response_code = has_errors ? 400 : 200;

            foreach (KeyValuePair<string, string> pair in replacements) {
                template = template.Replace (pair.Key, pair.Value);
            }

            Hashtable reply = new Hashtable ();

            reply["int_response_code"] = 200;
            // 200 OK
            reply["str_response_string"] = template;
            reply["content_type"] = "text/html";

            return reply;

            // TODO: Handle odd formats
            /*
            $giveawaystr = '"Label","Address"';
                if (preg_match('/'.preg_quote($giveawaystr).'/', $addresstext)) {
                    $format = 'csv';
                }

                $lines = explode("\n", $addresstext);
                $addresses = array();
                foreach($lines as $line) {
                    $line = trim($line);
                    if ($format == 'csv') {
                        if (preg_match('/^.*?,\"(.*?)\"$/', $line, $matches)) {
                            if ($matches[1] == 'Address') {
                                continue;
                            }
                            $addresses[] = $matches[1];
                        }
                    } else {
                        $addresses[] = $line;
                    }
                }
            */
        }
        public string AddressForAvatar(string user_identifier, string user_email)
        {
            string query = "select a.btc_address as btc_address from opensim_btc_addresses a left outer join opensim_btc_transactions t on a.btc_address=t.btc_address where a.user_identifier=?user_identifier AND t.confirmation_sent_ts > 0 OR t.id IS NULL limit 1;";

            using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
            {

                dbcon.Open();

                MySqlCommand cmd = new MySqlCommand( query, dbcon);

                try
                {
                    using (cmd)
                    {
                        cmd.Parameters.AddWithValue("?user_identifier", m_user_identifier);

                        using (MySqlDataReader dbReader = cmd.ExecuteReader())
                        {
                            if (dbReader.Read())
                            {
                                m_btc_address = (string)dbReader["btc_address"];
                            }
                        }

                        cmd.Dispose();

                        return m_btc_address;

                    }
                }
                catch (Exception e)
                {
                    m_log.Error("[FreeMoney] Error fetching addresses for avatar: "+e.ToString());
                    //m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
                    //return "";
                }

            }

            if (user_email == "") {
                return "";
            }

            // No address yet - try to create one with an email service.
            BitcoinAddressForEmailService serv = new BitcoinAddressForEmailService(m_config);
            string new_btc_address = serv.BTCAddressForEmail(user_email);

            if (new_btc_address != "") {
                // create a new object - we may want to make this whole method static.
                BitcoinAddress addr = new BitcoinAddress(m_connectionString, m_config);
                if (addr.Create(user_identifier, new_btc_address)) {
                    return new_btc_address;
                }
            }

            return "";
        }
        public Hashtable BitcoinInitializePaymentPage(Hashtable request)
        {
            Dictionary<string, object> postvals = ServerUtils.ParseQueryString ((string)request["body"]);

            UUID txnID = new UUID ((string)postvals["txn"]);

            if (!m_transactionsInProgress.ContainsKey (txnID)) {
                Hashtable ereply = new Hashtable ();

                ereply["int_response_code"] = 404;
                // 200 OK
                ereply["str_response_string"] = "Invalid Transaction";
                ereply["content_type"] = "text/html";

                return ereply;
            }

            FreeMoneyTransaction txn = m_transactionsInProgress[txnID];

            string baseUrl = m_scenes[0].RegionInfo.ExternalHostName + ":" + m_scenes[0].RegionInfo.HttpPort;

            bool has_errors = false;

            BitcoinTransaction btc_trans = InitializeBitcoinTransaction(txn, baseUrl);
            has_errors = btc_trans.HasErrors();

            if (has_errors) {
                string error_message = "<p><strong>Sorry, I couldn't set up this payment.</strong></p>";
                return ShowUserPage(request, baseUrl, txn, error_message);
            }

            string user_identifier = txn.From.ToString();
            BitcoinAddress count_btc_addr = new BitcoinAddress(m_connectionString, m_btcconfig);
            int count_all_addresses = count_btc_addr.CountAddressesForAvatar(user_identifier, true);
            int count_usable_addresses = count_btc_addr.CountAddressesForAvatar(user_identifier, false);

            Dictionary<string, string> replacements = new Dictionary<string, string> ();
            //replacements.Add ("{BTC_SESSION_ID}",  HttpUtility.HtmlEncode(btc_session_id));
            //TODO put HttpUtility back
            replacements.Add ("{BTC_SESSION_ID}", GetSessionKey( txn.From ).ToString());
            bool is_submit = true; // TODO
            if (is_submit) {
                replacements.Add ("{BTC_ERRORS}",  "");
                replacements.Add ("{BTC_DISABLE_COMPLETE_START}",  "<!--");
                replacements.Add ("{BTC_DISABLE_COMPLETE_END}",  "-->");
                replacements.Add ("{BTC_DISABLE_INCOMPLETE_START}",  "");
                replacements.Add ("{BTC_DISABLE_INCOMPLETE_END}",  "");
            } else {
                replacements.Add ("{BTC_ERRORS}",  "");
                replacements.Add ("{BTC_DISABLE_INCOMPLETE_START}",  "<!--");
                replacements.Add ("{BTC_DISABLE_INCOMPLETE_END}",  "-->");
                replacements.Add ("{BTC_DISABLE_COMPLETE_START}",  "");
                replacements.Add ("{BTC_DISABLE_COMPLETE_END}",  "");
            }
            replacements.Add ("{BTC_AMOUNT}", btc_trans.GetBTCAmount().ToString());
            replacements.Add ("{BTC_ADDRESS}", btc_trans.GetBTCAddress().ToString());
            replacements.Add ("{BTC_COUNT_ALL_ADDRESSES}",  count_all_addresses.ToString());
            replacements.Add ("{BTC_COUNT_USABLE_ADDRESSES}", count_usable_addresses.ToString());

            string template;
            string template_name = "bitcoin-pay-template.htm";

            try {
                template = File.ReadAllText (template_name);
            } catch (IOException) {
                template = "Error: bitcoin-pay-template.htm does not exist.";
                //m_log.Error ("[FreeMoney] Unable to load template file.");
                m_log.Error("[FreeMoney] Could not load template file bitcoin-pay-template.htm");
                has_errors = true;
            }

            int response_code = has_errors ? 400 : 200;

            foreach (KeyValuePair<string, string> pair in replacements) {
                template = template.Replace (pair.Key, pair.Value);
            }

            Hashtable reply = new Hashtable ();

            reply["int_response_code"] = 200;
            // 200 OK
            reply["str_response_string"] = template;
            reply["content_type"] = "text/html";

            return reply;
        }