Describes a connection request.
Inheritance: MeshItem
        /// <summary>
        /// Initiate a device connection request.
        /// </summary>
        /// <param name="SignedDeviceProfile">The device profile to register.</param>
        /// <returns>The service response.</returns>
        public ConnectStartResponse ConnectRequest (SignedDeviceProfile SignedDeviceProfile) {
            this.SignedDeviceProfile = SignedDeviceProfile;

            var ConnectionRequest = new ConnectionRequest(AccountID, SignedDeviceProfile);

            var DeviceRequest = new ConnectStartRequest();
            DeviceRequest.SignedRequest = ConnectionRequest.Signed;
            DeviceRequest.AccountID = AccountID;
            var DeviceResponse = MeshService.ConnectStart(DeviceRequest);


            return DeviceResponse;
            }
        /// <summary>
        /// Sign a connection request.
        /// </summary>
        /// <param name="ConnectionRequest">Connection request to sign.</param>
        public SignedConnectionRequest (ConnectionRequest ConnectionRequest) {
            var SignedDeviceProfile = ConnectionRequest.Device;
            var DeviceProfile = SignedDeviceProfile.Data;

            Identifier = DeviceProfile.UDF;

            var PrivateKey = DeviceProfile.DeviceSignatureKey.PrivateKey;
            SignedData = new JoseWebSignature(ConnectionRequest.GetBytes(), PrivateKey);
            }
        /// <summary>
        /// Unpack the connection request data.
        /// </summary>
        /// <returns>The unpacked request.</returns>
        public ConnectionRequest Unpack() {
            _Signed = null;


            var Reader = JSONReader.OfData(SignedData.Payload);
            var Profile = ConnectionRequest.FromTagged(Reader);

            _Signed = Profile;
            return _Signed;
            }
        public void MeshStore () {

            File.Delete(Store);
            File.Delete(Portal);
            Mesh = new Mesh(Service, Store, Portal);

            Mesh.CheckAccount(AccountID);

            var DevProfile = new SignedDeviceProfile(Device1, Device1Description);
            var UserProfile = new PersonalProfile(DevProfile);

            var SignedProfile = UserProfile.Signed;
            Mesh.CreateAccount(AccountID, SignedProfile);

            // Add the device to the profile entry in the parent.

            var PasswordProfile = new PasswordProfile(true);

            var SignedPasswordProfile = PasswordProfile.Signed;

            SignedProfile = UserProfile.Signed;
            Mesh.AddProfile(SignedPasswordProfile); 
            Mesh.UpdateProfile(SignedProfile);

            // ok now pull the profile as a client.

            var Account = Mesh.GetAccount(AccountID); 
            var AccountPersonalProfile = Mesh.GetPersonalProfile(Account.UserProfileUDF);
            AccountPersonalProfile.SignedDeviceProfile = DevProfile;

            var PasswordEntry = AccountPersonalProfile.GetPasswordProfile();
            var SignedPasswordProfile2 = 
                Mesh.GetProfile(PasswordEntry.Identifier) as SignedProfile;

            var AccountPasswordProfile = PasswordProfile.Get(
                            SignedPasswordProfile2, AccountPersonalProfile);
            AccountPasswordProfile.Add(PWDSite, PWDUser, PWDPassword);

            // Implement the second way to do things, cleaner.
            //var AccountSignedPassword = new SignedPasswordProfile(AccountPasswordProfile);
            var AccountSignedPassword = AccountPasswordProfile.Signed;
            Mesh.UpdateProfile(AccountSignedPassword);

            // Now add a new device

            var DevProfile2 = new SignedDeviceProfile(Device2, Device2Description);

            // Post Connect Request
            Mesh.GetChainToken();
            var ConnectionRequest = new ConnectionRequest(Account, DevProfile2);

            Mesh.PostConnectionRequest(ConnectionRequest.Signed, 
                Account.UniqueID);

            // Get list of pending requests
            Mesh.GetPendingRequests(Account.AccountID);

            // Accept pending request


            var ConnectionResult = new ConnectionResult();
            ConnectionResult.Result = "Accept";
            ConnectionResult.Device = DevProfile2;
            var SignedConnectionResult = new SignedConnectionResult(ConnectionResult,
                AccountPersonalProfile.GetAdministrationKey());
            Mesh.CloseConnectionRequest(Account.AccountID, SignedConnectionResult);


            // Pull password data 
            Mesh.GetRequestStatus(Account.AccountID, DevProfile2.UDF);


            // decrypt using device2 credential
            var SignedPasswordProfile3 = 
                Mesh.GetProfile(PasswordEntry.Identifier) as SignedProfile;
            var PP3 = PasswordProfile.Get(SignedPasswordProfile3, AccountPersonalProfile);
            var PasswordPrivate = PP3.Private;


            }
		/// <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 ConnectionRequest  FromTagged (JSONReader JSONReader) {
			ConnectionRequest Out = null;

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

			string token = JSONReader.ReadToken ();

			switch (token) {

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

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

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

			return Out;
			}