public Bosh(string url, Jid jid, string password, IBoshTransport transport)
 {
     _url       = url;
     _jid       = jid;
     _password  = password;
     _transport = transport;
 }
        //
        // Internal
        //

        internal static Vault Open(string username,
                                   string accountPassword,
                                   string vaultPassword,
                                   IRestTransport restTransport,
                                   IBoshTransport boshTransport)
        {
            return(new Vault(Client.OpenVault(username, accountPassword, vaultPassword, restTransport, boshTransport)));
        }
        public static Account[] OpenVault(string username,
                                          string accountPassword,
                                          string vaultPassword,
                                          IRestTransport restTransport,
                                          IBoshTransport boshTransport)
        {
            var rest = new RestClient(restTransport);

            // 1. Login
            var(sessionCookie, authCookies) = Login(username, accountPassword, rest);

            try
            {
                // 2. Get XMPP info
                var xmpp = GetXmppInfo(authCookies, rest);

                // 3. The server returns a bunch of alternative URLs with the XMPP BOSH Js library which
                //    are located on different domains. We need to pick one and all the following request
                //    are done using this domain and its sub and sibling domains.
                var jsLibraryHost = ChooseJsLibraryHost(xmpp);

                // 4. Generate JID
                var jid = GenerateJid(xmpp.UserId, jsLibraryHost);

                // 5. Get notify server BOSH url
                var httpsBoshUrl = GetBoshUrl(jid, jsLibraryHost, rest);

                // 6. "find_bosh_bind" call returns a https:// link which doesn't work with the web sockets.
                //    It need to be converted to the wss:// before it could be used.
                var wssBoshUrl = ConvertHttpsBoshUrlToWss(httpsBoshUrl);

                // 6. Connect to the notify XMPP BOSH server
                var bosh = new Bosh(wssBoshUrl, jid, xmpp.XmppCredentials.Password, boshTransport);
                bosh.Connect();

                // 7. Get DB info which mainly contains the encryption settings (key derivation info)
                var dbInfoBlob = bosh.GetChanges(GetDatabaseInfoCommand, GetDatabaseInfoCommandId)
                                 .Where(x => x.Type == "Database")
                                 .Select(x => x.Data)
                                 .FirstOrDefault()?
                                 .Decode64();

                if (dbInfoBlob == null)
                {
                    throw MakeError("Database info is not found in the response");
                }

                var dbInfo = DatabaseInfo.Parse(dbInfoBlob);

                var version = dbInfo.Version;
                if (!SupportedDbVersions.Contains(version))
                {
                    throw new UnsupportedFeatureException($"Database version {version} is not supported");
                }

                var encryptionKey = Util.DeriveEncryptionKey(vaultPassword, dbInfo);
                var authKey       = Util.DeriveMasterPasswordAuthKey(jid.UserId, encryptionKey, dbInfo);

                // 8. Get DB that contains all of the accounts
                // TODO: Test on a huge vault to see if the accounts come in batches and
                //       we need to make multiple requests
                var db = bosh.GetChanges(GetDatabaseCommand, GetDatabaseCommandId, authKey.ToBase64());

                return(Parser.ParseVault(db, encryptionKey).ToArray());
            }
            finally
            {
                // 9. Logout
                Logout(sessionCookie, authCookies, rest);
            }
        }