private async Task <VaultOnline> GetVault()
        {
            var auth     = GetConnectedAuthContext();
            var authMock = Mock.Get(auth);

            authMock
            .Setup(x => x.ExecuteAuthCommand(It.IsAny <SyncDownCommand>(), It.IsAny <Type>(), It.IsAny <bool>()))
            .Returns <SyncDownCommand, Type, bool>((c, t, b) => Task.FromResult((KeeperApiResponse)_vaultEnv.GetSyncDownResponse()));

            var vault = new VaultOnline(auth);
            await vault.SyncDown();

            return(vault);
        }
        private static async Task Main()
        {
            Console.CancelKeyPress += (s, e) => { Environment.Exit(-1); };

            // Keeper SDK needs a storage to save configuration
            // such as: last login name, device token, etc
            var configuration = new JsonConfigurationStorage("test.json");


            var prompt = "Enter Email Address: ";

            if (!string.IsNullOrEmpty(configuration.LastLogin))
            {
                Console.WriteLine($"Default Email Address: {configuration.LastLogin}");
            }

            Console.Write(prompt);
            var username = Console.ReadLine();

            if (string.IsNullOrEmpty(username))
            {
                if (string.IsNullOrEmpty(configuration.LastLogin))
                {
                    Console.WriteLine("Bye.");
                    return;
                }

                username = configuration.LastLogin;
            }

            var inReadLine = false;

            var authFlow = new AuthSync(configuration);

            authFlow.UiCallback = new AuthSyncCallback(() =>
            {
                if (!inReadLine)
                {
                    return;
                }
                if (authFlow.Step.State == AuthState.Connected || authFlow.Step.State == AuthState.Error)
                {
                    Console.WriteLine("Press <Enter>");
                }
                else
                {
                    PrintStepHelp(authFlow.Step);
                    PrintStepPrompt(authFlow.Step);
                }
            },
                                                       Console.WriteLine);

            // Login to Keeper
            Console.WriteLine("Logging in...");

            var lastState = authFlow.Step.State;
            await authFlow.Login(username);

            while (!authFlow.IsCompleted)
            {
                if (authFlow.Step.State != lastState)
                {
                    PrintStepHelp(authFlow.Step);
                }

                lastState = authFlow.Step.State;
                PrintStepPrompt(authFlow.Step);
                inReadLine = true;
                var cmd = ReadInput();
                inReadLine = false;
                if (string.IsNullOrEmpty(cmd))
                {
                    continue;
                }

                try
                {
                    await ProcessCommand(authFlow, cmd);
                }
                catch (KeeperAuthFailed)
                {
                    Console.WriteLine("Invalid username or password");
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }

            if (authFlow.Step is ErrorStep es)
            {
                Console.WriteLine(es.Message);
            }
            if (!authFlow.IsAuthenticated())
            {
                return;
            }

            var auth  = authFlow;
            var vault = new VaultOnline(auth);

            Console.WriteLine("\nRetrieving records...");
            await vault.SyncDown();

            Console.WriteLine($"Hello {username}!");
            Console.WriteLine($"Vault has {vault.RecordCount} records.");

            // Find record with title "Google"
            var search = vault.Records.FirstOrDefault(x => string.Compare(x.Title, "Google", StringComparison.InvariantCultureIgnoreCase) == 0);

            // Create a record if it does not exist.
            if (search == null)
            {
                search = new PasswordRecord
                {
                    Title    = "Google",
                    Login    = "******",
                    Password = "******",
                    Link     = "https://google.com",
                    Notes    = "Stores google credentials"
                };
                search = await vault.CreateRecord(search);
            }

            var nsd3 = vault.LoadNonSharedData <NonSharedData3>(search.Uid);

            nsd3.Data1 = "1";
            nsd3.Data3 = "3";
            await vault.StoreNonSharedData(search.Uid, nsd3);

            var nsd2 = vault.LoadNonSharedData <NonSharedData2>(search.Uid);

            nsd2.Data2 = "2";
            await vault.StoreNonSharedData(search.Uid, nsd2);

            // Update record.
            search.SetCustomField("Security Token", "11111111");
            search = await vault.UpdateRecord(search);

            // find file attachment.
            var attachment = search.Attachments
                             .FirstOrDefault(x => string.Compare(x.Title, "google", StringComparison.InvariantCultureIgnoreCase) == 0);

            if (attachment == null)
            {
                // Upload local file "google.txt".
                // var uploadTask = new FileAttachmentUploadTask("google.txt")
                var fileContent = Encoding.UTF8.GetBytes("Google");
                using (var stream = new MemoryStream(fileContent))
                {
                    var uploadTask = new AttachmentUploadTask(stream)
                    {
                        Title    = "Google",
                        Name     = "google.txt",
                        MimeType = "text/plain"
                    };
                    await vault.UploadAttachment(search, uploadTask);

                    await vault.UpdateRecord(search, false);
                }
            }
            else
            {
                // Download attachment into the stream
                // The stream could be a local file "google.txt"
                // using (var stream = File.OpenWrite("google.txt"))
                using (var stream = new MemoryStream())
                {
                    await vault.DownloadAttachment(search, attachment.Id, stream);
                }

                // Delete attachment. Remove it from the record
                search.Attachments.Remove(attachment);
                await vault.UpdateRecord(search, false);
            }

            // Find shared folder with name "Google".
            var sharedFolder = vault.SharedFolders
                               .FirstOrDefault(x => string.Compare(x.Name, "Google", StringComparison.InvariantCultureIgnoreCase) == 0);

            if (sharedFolder == null)
            {
                // Create shared folder.
                var folder = await vault.CreateFolder("Google",
                                                      null,
                                                      new SharedFolderOptions
                {
                    ManageRecords = true,
                    ManageUsers   = false,
                    CanEdit       = false,
                    CanShare      = false,
                });

                vault.TryGetSharedFolder(folder.FolderUid, out sharedFolder);
            }

            // Add user to shared folder.
            try
            {
                await vault.PutUserToSharedFolder(sharedFolder.Uid,
                                                  "*****@*****.**",
                                                  UserType.User,
                                                  new SharedFolderUserOptions
                {
                    ManageRecords = false,
                    ManageUsers   = false,
                });
            }
            catch (Exception e)
            {
                Console.WriteLine($"Add user to Shared Folder error: {e.Message}");
            }


            // Add record to shared folder.
            await vault.MoveRecords(new[] { new RecordPath {
                                                RecordUid = search.Uid
                                            } }, sharedFolder.Uid, true);

            if (auth.AuthContext.IsEnterpriseAdmin)
            {
                // Load enterprise data.
                var enterprise = new EnterpriseData(auth);
                await enterprise.GetEnterpriseData();

                // Find team with name "Google".
                var team = enterprise.Teams
                           .FirstOrDefault(x => string.Compare(x.Name, "Google", StringComparison.InvariantCultureIgnoreCase) == 0);
                if (team == null)
                {
                    // Create team.
                    team = await enterprise.CreateTeam(new EnterpriseTeam
                    {
                        Name            = "Google",
                        RestrictEdit    = false,
                        RestrictSharing = true,
                        RestrictView    = false,
                    });
                }

                if (team != null)
                {
                    // Add users to the "Google" team.
                    await enterprise.AddUsersToTeams(
                        new[] { "*****@*****.**", "*****@*****.**" },
                        new[] { team.Uid },
                        Console.WriteLine);
                }
            }

            Console.WriteLine("Press any key to quit");
            Console.ReadKey();
        }