/// <summary>
 /// Encrypt all data in the dictionary
 /// </summary>
 /// <param name="password">Password to use for encryption</param>
 /// <param name="callback">Callback to run after initialization (if needed) and encryption is finished</param>
 public void EncryptAll(string password, Action callback = null)
 {
     if (EncryptionService.IterationsPerMinute == null)
     {
         if (EncryptionService.IsInitializationRunning)
         {
             EncryptionService.InitializationCallback = () => {
                 var keyPassword = EncryptionService.GetKeyInBytes(password);
                 EncryptAll(keyPassword);
                 callback?.Invoke();
             };
         }
     }
     else
     {
         var keyPassword = EncryptionService.GetKeyInBytes(password);
         EncryptAll(keyPassword);
         callback?.Invoke();
     }
 }
        /// <summary>
        /// Compute partial encryption of the original data based on individual key derived from hash of main password and <see cref="Salt"/>
        /// </summary>
        /// <param name="encryptionService">Encryption service to use for encryption</param>
        /// <param name="keyPassword">Hash of main password</param>
        public void ComputePartEncryption(EncryptionService encryptionService, byte[] keyPassword)
        {
            if (Original != null)
            {
                if (Salt == null)
                {
                    Salt = encryptionService.GenerateRandomCryptographicKey(32);
                }
                var newKeyPassword = encryptionService.GetIndividualKeyInBytes(keyPassword, Salt);
                EncryptedPart = encryptionService.Encrypt(newKeyPassword, Original.ToString());

                var check = encryptionService.Decrypt(newKeyPassword, EncryptedPart);
                if (check != Original.ToString())
                {
                    throw new Exception("Can not be decrypted.");
                }

                Original = null;
            }
        }
        /// <summary>
        /// Decrypt the original data from only partially encrypted/decrypted data
        /// </summary>
        /// <typeparam name="T">Type of result</typeparam>
        /// <param name="encryptionService">Encryption service to use for decryption</param>
        /// <param name="keyPassword">Hash of main password</param>
        /// <param name="convert">Converter from decrypted string into type T; not needed to specify if result is string, int, double or bool</param>
        /// <returns>Decrypted data of type T</returns>
        public T Decrypt <T>(EncryptionService encryptionService, byte[] keyPassword, Func <string, T> convert = null)
        {
            T result = default(T);

            if (EncryptedPart != null)
            {
                if (Salt == null)
                {
                    Salt = encryptionService.GenerateRandomCryptographicKey(32);
                }
                var individualKeyPassword = encryptionService.GetIndividualKeyInBytes(keyPassword, Salt);
                var decryptedPart         = encryptionService.Decrypt(individualKeyPassword, EncryptedPart);
                if (typeof(T) == typeof(string))
                {
                    result = (T)Convert.ChangeType(decryptedPart, typeof(string));
                }
                else if (typeof(T) == typeof(int))
                {
                    result = (T)Convert.ChangeType(decryptedPart, typeof(int));
                }
                else if (typeof(T) == typeof(double))
                {
                    result = (T)Convert.ChangeType(decryptedPart, typeof(double));
                }
                else if (typeof(T) == typeof(bool))
                {
                    result = (T)Convert.ChangeType(decryptedPart, typeof(bool));
                }
                else if (convert != null)
                {
                    result = convert(decryptedPart);
                }
            }
            Original = result;
            return(result);
        }
 /// <summary>
 /// Decrypt first part of encryption layer
 /// </summary>
 /// <param name="encryptionService">Encryption service to use for decryption</param>
 /// <param name="keyPassword">Hash of main password</param>
 public void DecryptPart(EncryptionService encryptionService, byte[] keyPassword)
 {
     EncryptedPart = encryptionService.Decrypt(keyPassword, Encrypted);
 }
        /// <summary>
        /// Encrypt all that that were not yet encrypted
        /// </summary>
        /// <param name="password">Password to use for encryption</param>
        public void EncryptNotEncrypted(string password)
        {
            var keyPasssword = EncryptionService.GetKeyInBytes(password);

            EncryptNotEncrypted(keyPasssword);
        }