/// <summary>
        /// Write this authenticator into an XmlWriter
        /// </summary>
        /// <param name="writer">XmlWriter to receive authenticator</param>
        public void WriteToWriter(XmlWriter writer)
        {
            writer.WriteStartElement("authenticator");
            writer.WriteAttributeString("type", this.GetType().FullName);
            //
            writer.WriteStartElement("servertimediff");
            writer.WriteString(ServerTimeDiff.ToString());
            writer.WriteEndElement();
            //
            writer.WriteStartElement("secretdata");
            string data = SecretData;

            StringBuilder encryptionTypes = new StringBuilder();

            if ((PasswordType & PasswordTypes.Explicit) != 0)
            {
                string encrypted = Encrypt(data, Password);

                // test the encryption
                string decrypted = Decrypt(encrypted, Password, true);
                if (string.Compare(data, decrypted) != 0)
                {
                    throw new InvalidEncryptionException(data, Password, encrypted, decrypted);
                }
                data = encrypted;

                encryptionTypes.Append("y");
            }
            if ((PasswordType & PasswordTypes.User) != 0)
            {
                // we encrypt the data using the Windows User account key
                byte[] plain  = StringToByteArray(data);
                byte[] cipher = ProtectedData.Protect(plain, null, DataProtectionScope.CurrentUser);
                data = ByteArrayToString(cipher);
                encryptionTypes.Append("u");
            }
            if ((PasswordType & PasswordTypes.Machine) != 0)
            {
                // we encrypt the data using the Local Machine account key
                byte[] plain  = StringToByteArray(data);
                byte[] cipher = ProtectedData.Protect(plain, null, DataProtectionScope.LocalMachine);
                data = ByteArrayToString(cipher);
                encryptionTypes.Append("m");
            }
            writer.WriteAttributeString("encrypted", encryptionTypes.ToString());
            writer.WriteString(data);
            writer.WriteEndElement();
            //
            if (RestoreCodeVerified == true)
            {
                writer.WriteStartElement("restorecodeverified");
                writer.WriteString(bool.TrueString.ToLower());
                writer.WriteEndElement();
            }
            //
            writer.WriteEndElement();
        }
        /// <summary>Write this authenticator into an XmlWriter</summary>
        /// <param name="writer">XmlWriter to receive authenticator</param>
        public void WriteToWriter(XmlWriter writer)
        {
            writer.WriteStartElement("authenticatordata");
            //writer.WriteAttributeString("type", this.GetType().FullName);
            string encrypted = EncodePasswordTypes(PasswordType);

            if (string.IsNullOrEmpty(encrypted) == false)
            {
                writer.WriteAttributeString("encrypted", encrypted);
            }

            if (PasswordType != PasswordTypes.None)
            {
                writer.WriteRaw(EncryptedData);
            }
            else
            {
                writer.WriteStartElement("servertimediff");
                writer.WriteString(ServerTimeDiff.ToString());
                writer.WriteEndElement();
                //
                writer.WriteStartElement("lastservertime");
                writer.WriteString(LastServerTime.ToString());
                writer.WriteEndElement();
                //
                writer.WriteStartElement("secretdata");
                writer.WriteString(SecretData);
                writer.WriteEndElement();

                WriteExtraXml(writer);
            }

            /*
             *                      if (passwordType != Authenticator.PasswordTypes.None)
             *                      {
             *                              //string data = this.EncryptedData;
             *                              //if (data == null)
             *                              //{
             *                              //	using (MemoryStream ms = new MemoryStream())
             *                              //	{
             *                              //		XmlWriterSettings settings = new XmlWriterSettings();
             *                              //		settings.Indent = true;
             *                              //		settings.Encoding = Encoding.UTF8;
             *                              //		using (XmlWriter encryptedwriter = XmlWriter.Create(ms, settings))
             *                              //		{
             *                              //			Authenticator.PasswordTypes savedpasswordType = PasswordType;
             *                              //			PasswordType = Authenticator.PasswordTypes.None;
             *                              //			WriteToWriter(encryptedwriter);
             *                              //			PasswordType = savedpasswordType;
             *                              //		}
             *                              //		data = Authenticator.ByteArrayToString(ms.ToArray());
             *                              //	}
             *
             *                              //	data = Authenticator.EncryptSequence(data, PasswordType, Password);
             *                              //}
             *
             *                              writer.WriteString(this.EncryptedData);
             *                              writer.WriteEndElement();
             *
             *                              return;
             *                      }
             *
             *                      //
             *                      writer.WriteStartElement("servertimediff");
             *                      writer.WriteString(ServerTimeDiff.ToString());
             *                      writer.WriteEndElement();
             *                      //
             *                      writer.WriteStartElement("secretdata");
             *        writer.WriteString(SecretData);
             *        writer.WriteEndElement();
             *
             *                      WriteExtraXml(writer);
             */

            writer.WriteEndElement();
        }