/// <summary>
        /// Create and recover profile.
        /// </summary>
        void KeyRecovery() {

            // Create escrow keyshares for 2 our of 3
            OfflineEscrowEntry = new OfflineEscrowEntry(PersonalProfile, 3, 2);

            Portal.Label(LabelEscrow);
            // Publish key escrow to the Mesh
            MeshClient.Publish(OfflineEscrowEntry);

            // Recover encryption key from two shares
            var share1 = OfflineEscrowEntry.KeyShares[0].Text;
            var share2 = OfflineEscrowEntry.KeyShares[1].Text;

            // Get recovery data
            string[] TestShares = { share1, share2 };
            var RecoveryKey = new Secret (TestShares);

            // Determine identifier
            var Identifier = UDF.ToString(UDF.FromEscrowed(
                RecoveryKey.Key, 150));

            // Here need a call to pull the data
            Portal.Label(LabelRecover);

            MeshClient.Recover(Identifier);
            }
        void MakeCheckRecovery() {
            OfflineEscrowEntry = new OfflineEscrowEntry(UserProfile, 3, 2);
            share1 = OfflineEscrowEntry.KeyShares[0].Text;
            share2 = OfflineEscrowEntry.KeyShares[1].Text;
            share3 = OfflineEscrowEntry.KeyShares[2].Text;

            var PublishResponse = MeshClient.Publish(OfflineEscrowEntry);

            string[] TestShares = { share1, share2 };
            var RecoveryKey = RecoverProfile(TestShares);

            if (RecoveryKey != OfflineEscrowEntry.Identifier) {
                //throw new Exception("Recovery failure!");
                Trace.WriteLine("****Fail {0}");
                }
            }
        /// <summary>
        /// Publish an offline escrow entry to the mesh.
        /// </summary>
        /// <param name="OfflineEscrowEntry">The escrow entry to publish</param>
        /// <returns>The service response.</returns>
        public PublishResponse Publish(OfflineEscrowEntry OfflineEscrowEntry) {
            var PublishRequest = new PublishRequest();
            PublishRequest.Entry = OfflineEscrowEntry;

            var PublishResponse = MeshService.Publish(PublishRequest);
            return PublishResponse;
            }
        public bool Calculate() {

            if (NewDeviceProfile) {
                var NewProfile = new SignedDeviceProfile(DeviceName, DeviceDescription);
                _DeviceProfile = NewProfile;
                }
            else {
                _DeviceProfile = ProfileManager.RegistrationMachine.Device.Device;
                }
            _PersonalProfile = new PersonalProfile(_DeviceProfile);


            // Have got the profile, escrow the key
            if (EscrowKeys) {
                var OfflineEscrowEntry = new
                    OfflineEscrowEntry(_PersonalProfile, EscrowShares, EscrowQuorum);

                EscrowKeyShares = new List<Goedel.Trojan.Object>();

                int Index = 1;
                foreach (var KeyShare in OfflineEscrowEntry.KeyShares) {
                    var Share = new Share();
                    Share.Number.Value = Index++;
                    Share.Value.Value = KeyShare.Text;
                    EscrowKeyShares.Add(Share);
                    }
                }

            if (WebApplicationProfile) {
                PasswordProfile = new PasswordProfile(PersonalProfile);
                PasswordProfile.AddDevice(_DeviceProfile);
                }

            // Mail profiles here
            /*
                             foreach (var MailAccountInfo in MailAccountInfos) {
                                // Add in the S/MIME parameters and update the profile
                                //if (!MailAccountInfo.GotSMIME) {
                                    MailAccountInfo.GenerateSMIME();
                                    MailAccountInfo.Update();
                                    //}

                                var MailProfile = new MailProfile(UserProfile, MailAccountInfo);
                                MailProfile.AddDevice(ThisDevice);

                                //var SignedMailProfile = new SignedApplicationProfile(MailProfile);
                                MeshClient.Publish(MailProfile.Signed);
                                }
             * */

            // Network profiles here
            /*
                                var NetworkProfile = new NetworkProfile(UserProfile);
                                NetworkProfile.AddDevice(ThisDevice);
                                MeshClient.Publish(NetworkProfile.Signed);
            */

            // SSH profiles here


            SignedPasswordProfile = PasswordProfile.Signed;
            _SignedPersonalProfile = new SignedPersonalProfile(PersonalProfile);

            return true;
            }
		/// <summary>
        /// Construct an instance from the specified tagged JSONReader stream.
        /// </summary>
        /// <param name="JSONReader">Input stream</param>
        /// <param name="Out">The created object</param>
        public static void Deserialize(JSONReader JSONReader, out JSONObject Out) {
	
			JSONReader.StartObject ();
            if (JSONReader.EOR) {
                Out = null;
                return;
                }

			string token = JSONReader.ReadToken ();
			Out = null;

			switch (token) {

				case "PublicKey" : {
					var Result = new PublicKey ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "SignedData" : {
					var Result = new SignedData ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "EncryptedData" : {
					var Result = new EncryptedData ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "Connection" : {
					var Result = new Connection ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "Entry" : {
					var Result = new Entry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "SignedProfile" : {
					var Result = new SignedProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "Profile" : {
					Out = null;
					throw new Exception ("Can't create abstract type");
					}


				case "SignedDeviceProfile" : {
					var Result = new SignedDeviceProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "DeviceProfile" : {
					var Result = new DeviceProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "DevicePrivateProfile" : {
					var Result = new DevicePrivateProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "SignedMasterProfile" : {
					var Result = new SignedMasterProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "MasterProfile" : {
					var Result = new MasterProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "SignedPersonalProfile" : {
					var Result = new SignedPersonalProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "PersonalProfile" : {
					var Result = new PersonalProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "SignedApplicationProfile" : {
					var Result = new SignedApplicationProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "EncryptedProfile" : {
					var Result = new EncryptedProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "ApplicationProfile" : {
					var Result = new ApplicationProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "ApplicationProfilePrivate" : {
					var Result = new ApplicationProfilePrivate ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "ApplicationProfileEntry" : {
					var Result = new ApplicationProfileEntry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "EscrowEntry" : {
					var Result = new EscrowEntry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "OfflineEscrowEntry" : {
					var Result = new OfflineEscrowEntry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "OnlineEscrowEntry" : {
					var Result = new OnlineEscrowEntry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "EscrowedKeySet" : {
					var Result = new EscrowedKeySet ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "ConnectionRequest" : {
					var Result = new ConnectionRequest ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "SignedConnectionRequest" : {
					var Result = new SignedConnectionRequest ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "ConnectionResult" : {
					var Result = new ConnectionResult ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}


				case "SignedConnectionResult" : {
					var Result = new SignedConnectionResult ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				default : {
					throw new Exception ("Not supported");
					}
				}	
			JSONReader.EndObject ();
            }
        /// <summary>
        /// Deserialize a tagged stream
        /// </summary>
        /// <param name="JSONReader">The input stream</param>
        /// <returns>The created object.</returns>		
        public static new OfflineEscrowEntry  FromTagged (JSONReader JSONReader) {
			OfflineEscrowEntry Out = null;

			JSONReader.StartObject ();
            if (JSONReader.EOR) {
                return null;
                }

			string token = JSONReader.ReadToken ();

			switch (token) {

				case "OfflineEscrowEntry" : {
					var Result = new OfflineEscrowEntry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				default : {
					//Ignore the unknown data
                    //throw new Exception ("Not supported");
                    break;
					}
				}
			JSONReader.EndObject ();

			return Out;
			}
        /// <summary>
        /// Deserialize a tagged stream
        /// </summary>
        /// <param name="JSONReader">The input stream</param>
        /// <returns>The created object.</returns>		
        public static new Entry  FromTagged (JSONReader JSONReader) {
			Entry Out = null;

			JSONReader.StartObject ();
            if (JSONReader.EOR) {
                return null;
                }

			string token = JSONReader.ReadToken ();

			switch (token) {

				case "Entry" : {
					var Result = new Entry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "SignedProfile" : {
					var Result = new SignedProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "SignedDeviceProfile" : {
					var Result = new SignedDeviceProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "SignedMasterProfile" : {
					var Result = new SignedMasterProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "SignedPersonalProfile" : {
					var Result = new SignedPersonalProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "SignedApplicationProfile" : {
					var Result = new SignedApplicationProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "SignedConnectionRequest" : {
					var Result = new SignedConnectionRequest ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "SignedConnectionResult" : {
					var Result = new SignedConnectionResult ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "Profile" : {
					Out = null;
					throw new Exception ("Can't create abstract type");
					}

				case "DeviceProfile" : {
					var Result = new DeviceProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "MasterProfile" : {
					var Result = new MasterProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "PersonalProfile" : {
					var Result = new PersonalProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "ApplicationProfile" : {
					var Result = new ApplicationProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "EncryptedProfile" : {
					var Result = new EncryptedProfile ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "ApplicationProfilePrivate" : {
					var Result = new ApplicationProfilePrivate ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "EscrowEntry" : {
					var Result = new EscrowEntry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "OfflineEscrowEntry" : {
					var Result = new OfflineEscrowEntry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				case "OnlineEscrowEntry" : {
					var Result = new OnlineEscrowEntry ();
					Result.Deserialize (JSONReader);
					Out = Result;
					break;
					}

				default : {
					//Ignore the unknown data
                    //throw new Exception ("Not supported");
                    break;
					}
				}
			JSONReader.EndObject ();

			return Out;
			}