protected override void ProcessRecord()
        {
            var db = new ClientConfigurationDbContext(this.ConnectionString, this.Schema);

            var entity        = db.Clients.Single(c => c.ClientId == this.Client.ClientId);
            var currentId     = entity.Id;
            var currentclient = entity.ToModel();

            var attachedEntry = db.Entry(entity);
            var newentity     = this.Client.ToEntity();

            newentity.Id = currentId;
            attachedEntry.CurrentValues.SetValues(newentity);

            // Synchronize nav properties - FIXME ugly
            foreach (var uri in currentclient.RedirectUris.Union(this.Client.RedirectUris).Distinct())
            {
                if (currentclient.RedirectUris.Contains(uri) && !this.Client.RedirectUris.Contains(uri))
                {
                    var urientity = entity.RedirectUris.First(x => x.Uri == uri);
                    db.Entry(urientity).State = System.Data.Entity.EntityState.Deleted;
                    entity.RedirectUris.Remove(urientity);
                }
                else if (!currentclient.RedirectUris.Contains(uri) && this.Client.RedirectUris.Contains(uri))
                {
                    entity.RedirectUris.Add(new ClientRedirectUri()
                    {
                        Uri = uri
                    });
                }
            }
            foreach (var uri in currentclient.PostLogoutRedirectUris.Union(this.Client.PostLogoutRedirectUris).Distinct())
            {
                if (currentclient.PostLogoutRedirectUris.Contains(uri) && !this.Client.PostLogoutRedirectUris.Contains(uri))
                {
                    var urientity = entity.PostLogoutRedirectUris.First(x => x.Uri == uri);
                    db.Entry(urientity).State = System.Data.Entity.EntityState.Deleted;
                    entity.PostLogoutRedirectUris.Remove(urientity);
                }
                else if (!currentclient.PostLogoutRedirectUris.Contains(uri) && this.Client.PostLogoutRedirectUris.Contains(uri))
                {
                    entity.PostLogoutRedirectUris.Add(new ClientPostLogoutRedirectUri()
                    {
                        Uri = uri
                    });
                }
            }
            foreach (var gt in currentclient.CustomGrantTypeRestrictions.Union(this.Client.CustomGrantTypeRestrictions).Distinct())
            {
                if (currentclient.CustomGrantTypeRestrictions.Contains(gt) && !this.Client.CustomGrantTypeRestrictions.Contains(gt))
                {
                    var gtentity = entity.CustomGrantTypeRestrictions.First(x => x.GrantType == gt);
                    db.Entry(gtentity).State = System.Data.Entity.EntityState.Deleted;
                    entity.CustomGrantTypeRestrictions.Remove(gtentity);
                }
                else if (!currentclient.CustomGrantTypeRestrictions.Contains(gt) && this.Client.CustomGrantTypeRestrictions.Contains(gt))
                {
                    entity.CustomGrantTypeRestrictions.Add(new ClientGrantTypeRestriction()
                    {
                        GrantType = gt
                    });
                }
            }
            foreach (var scope in currentclient.ScopeRestrictions.Union(this.Client.ScopeRestrictions).Distinct())
            {
                if (currentclient.ScopeRestrictions.Contains(scope) && !this.Client.ScopeRestrictions.Contains(scope))
                {
                    var scopenetity = entity.ScopeRestrictions.First(x => x.Scope == scope);
                    db.Entry(scopenetity).State = System.Data.Entity.EntityState.Deleted;
                    entity.ScopeRestrictions.Remove(scopenetity);
                }
                else if (!currentclient.ScopeRestrictions.Contains(scope) && this.Client.ScopeRestrictions.Contains(scope))
                {
                    entity.ScopeRestrictions.Add(new ClientScopeRestriction()
                    {
                        Scope = scope
                    });
                }
            }
            foreach (var provider in currentclient.IdentityProviderRestrictions.Union(this.Client.IdentityProviderRestrictions).Distinct())
            {
                if (currentclient.IdentityProviderRestrictions.Contains(provider) && !this.Client.ScopeRestrictions.Contains(provider))
                {
                    var idpentity = entity.IdentityProviderRestrictions.First(x => x.Provider == provider);
                    db.Entry(idpentity).State = System.Data.Entity.EntityState.Deleted;
                    entity.IdentityProviderRestrictions.Remove(idpentity);
                }
                else if (!currentclient.IdentityProviderRestrictions.Contains(provider) && this.Client.IdentityProviderRestrictions.Contains(provider))
                {
                    entity.IdentityProviderRestrictions.Add(new ClientIdPRestriction()
                    {
                        Provider = provider
                    });
                }
            }
            foreach (var secret in currentclient.ClientSecrets.Union(this.Client.ClientSecrets).Distinct())
            {
                if (currentclient.ClientSecrets.Any(x => x.Value == secret.Value) && !this.Client.ClientSecrets.Any(x => x.Value == secret.Value))
                {
                    entity.ClientSecrets.Remove(entity.ClientSecrets.First(x => x.Value == secret.Value));
                }
                else if (!currentclient.ClientSecrets.Any(x => x.Value == secret.Value) && this.Client.ClientSecrets.Any(x => x.Value == secret.Value))
                {
                    entity.ClientSecrets.Add(new Thinktecture.IdentityServer.EntityFramework.Entities.ClientSecret
                    {
                        ClientSecretType = secret.ClientSecretType,
                        Description      = secret.ClientSecretType,
                        Expiration       = secret.Expiration,
                        Value            = secret.Value
                    });
                }
            }
            foreach (var claim in currentclient.Claims.Union(this.Client.Claims).Distinct())
            {
                if (currentclient.Claims.Any(x => x.Type == claim.Type) && !this.Client.Claims.Any(x => x.Type == claim.Type))
                {
                    entity.Claims.Remove(entity.Claims.First(x => x.Type == claim.Type && x.Value == claim.Value));
                }
                else if (!currentclient.Claims.Any(x => x.Type == claim.Type) && this.Client.Claims.Any(x => x.Type == claim.Type))
                {
                    entity.Claims.Add(new Thinktecture.IdentityServer.EntityFramework.Entities.ClientClaim()
                    {
                        Type  = claim.Type,
                        Value = claim.Value
                    });
                }
            }

            try
            {
                db.SaveChanges();
            }
            catch (System.Data.Entity.Infrastructure.DbUpdateException dbue)
            {
                WriteError(new ErrorRecord(dbue.InnerException, "DbUpdateException", ErrorCategory.WriteError, entity));
                throw dbue;
            }
            WriteObject(entity.ToModel());
        }
        public Result <int> Update(ClientModel model, int id)
        {
            try
            {
                var result         = new Result <int>();
                var existingClient = clientContext.Clients
                                     .Where(x => x.Id == id)
                                     .Include(x => x.AllowedScopes)
                                     .Include(x => x.ClientSecrets)
                                     .Include(x => x.RedirectUris)
                                     .Include(x => x.PostLogoutRedirectUris)
                                     .Include(x => x.AllowedCorsOrigins)
                                     .Include(x => x.IdentityProviderRestrictions)
                                     .Include(x => x.Claims)
                                     .Include(x => x.AllowedCustomGrantTypes)
                                     .SingleOrDefault();


                if (existingClient == null)
                {
                    result.Exists = false;
                    return(result);
                }

                var duplicateClientId = clientContext.Clients
                                        .Where(x => x.ClientId == model.ClientId)
                                        .FirstOrDefault();

                if (duplicateClientId != null && duplicateClientId.Id != id)
                {
                    throw new Exception("pre-existing clientid");
                }

                clientContext.Entry(existingClient).CurrentValues.SetValues(model); // copy all values from object

                #region Update related properties


                var exRedirectUris = existingClient.RedirectUris.ToList();
                //delete redirect uri's that have been removed
                foreach (var item in exRedirectUris)
                {
                    if (!model.RedirectUris.Any(x => x.Id == item.Id))
                    {
                        existingClient.RedirectUris.Remove(item);
                    }
                }
                if (model.RedirectUris != null && model.RedirectUris.Any())
                {
                    //update and add new uris
                    foreach (var item in model.RedirectUris)
                    {
                        var exRedirectUri = existingClient.RedirectUris.FirstOrDefault(x => x.Id == item.Id);
                        if (exRedirectUri != null)
                        {
                            clientContext.Entry(exRedirectUri).CurrentValues.SetValues(item);
                        }
                        else
                        {
                            var redirectUri = new ClientRedirectUri
                            {
                                Uri = item.Uri,
                            };
                            existingClient.RedirectUris.Add(redirectUri);
                        }
                    }
                }


                //delete post redirect uri's that have been removed

                var exPostRedirectUris = existingClient.PostLogoutRedirectUris.ToList();
                foreach (var item in exPostRedirectUris)
                {
                    if (!model.PostLogoutRedirectUris.Any(x => x.Id == item.Id))
                    {
                        existingClient.PostLogoutRedirectUris.Remove(item);
                    }
                }

                if (model.PostLogoutRedirectUris != null && model.PostLogoutRedirectUris.Any())
                {
                    foreach (var item in model.PostLogoutRedirectUris)
                    {
                        var exPostRedirectUri = existingClient.PostLogoutRedirectUris.FirstOrDefault(x => x.Id == item.Id);
                        if (exPostRedirectUri != null)
                        {
                            clientContext.Entry(exPostRedirectUri).CurrentValues.SetValues(item);
                        }
                        else
                        {
                            var postRedirectUri = new ClientPostLogoutRedirectUri
                            {
                                Uri = item.Uri,
                            };
                            existingClient.PostLogoutRedirectUris.Add(postRedirectUri);
                        }
                    }
                }
                //update and add new post redirect uris



                var exIdProvRestrictions = existingClient.IdentityProviderRestrictions.ToList();
                foreach (var item in exIdProvRestrictions)
                {
                    if (!model.IdentityProviderRestrictions.Any(x => x.Id == item.Id))
                    {
                        existingClient.IdentityProviderRestrictions.Remove(item);
                    }
                }

                if (model.IdentityProviderRestrictions != null && model.IdentityProviderRestrictions.Any())
                {
                    foreach (var item in model.IdentityProviderRestrictions)
                    {
                        var exIdProvRestriction = existingClient.IdentityProviderRestrictions.FirstOrDefault(x => x.Id == item.Id);
                        if (exIdProvRestriction != null)
                        {
                            clientContext.Entry(exIdProvRestriction).CurrentValues.SetValues(item);
                        }
                        else
                        {
                            var IdentityProvRestriction = new ClientIdPRestriction
                            {
                                Provider = item.Provider,
                            };
                            existingClient.IdentityProviderRestrictions.Add(exIdProvRestriction);
                        }
                    }
                }
                //update and add new post redirect uris



                //delete post redirect uri's that have been removed


                //delete allowed scopes that have been removed

                var exScopes = existingClient.AllowedScopes.ToList();
                foreach (var item in exScopes)
                {
                    if (!model.AllowedScopes.Any(x => x.Id == item.Id))
                    {
                        existingClient.AllowedScopes.Remove(item);
                    }
                }

                if (model.AllowedScopes != null && model.AllowedScopes.Any())
                {
                    foreach (var item in model.AllowedScopes)
                    {
                        var exScope = existingClient.AllowedScopes.FirstOrDefault(x => x.Id == item.Id);
                        if (exScope != null)
                        {
                            clientContext.Entry(exScope).CurrentValues.SetValues(item);
                        }
                        else
                        {
                            var newScope = new ClientScope
                            {
                                Scope = item.Scope,
                            };
                            existingClient.AllowedScopes.Add(newScope);
                        }
                    }
                }



                //delete client claims that have been removed
                var exClaims = existingClient.Claims.ToList();
                foreach (var item in exClaims)
                {
                    if (!model.Claims.Any(x => x.Id == item.Id))
                    {
                        existingClient.Claims.Remove(item);
                    }
                }

                if (model.Claims != null && model.Claims.Any())
                {
                    //update and add new post redirect uris
                    foreach (var item in model.Claims)
                    {
                        var exClaim = existingClient.Claims.FirstOrDefault(x => x.Id == item.Id);
                        if (exClaim != null)
                        {
                            clientContext.Entry(exClaim).CurrentValues.SetValues(item);
                        }
                        else
                        {
                            var newClaim = new ClientClaim
                            {
                                Type  = item.Type,
                                Value = item.Value
                            };
                            existingClient.Claims.Add(newClaim);
                        }
                    }
                }

                //delete client claims that have been removed

                var exAllowedCors = existingClient.AllowedCorsOrigins.ToList();
                foreach (var item in exAllowedCors)
                {
                    if (!model.AllowedCorsOrigins.Any(x => x.Id == item.Id))
                    {
                        existingClient.AllowedCorsOrigins.Remove(item);
                    }
                }

                if (model.AllowedCorsOrigins != null && model.AllowedCorsOrigins.Any())
                {
                    //update and add new post redirect uris
                    foreach (var item in model.AllowedCorsOrigins)
                    {
                        var exAllowedCor = existingClient.AllowedCorsOrigins.FirstOrDefault(x => x.Id == item.Id);
                        if (exAllowedCor != null)
                        {
                            clientContext.Entry(exAllowedCor).CurrentValues.SetValues(item);
                        }
                        else
                        {
                            var newClientCor = new ClientCorsOrigin
                            {
                                Origin = item.Origin
                            };
                            existingClient.AllowedCorsOrigins.Add(newClientCor);
                        }
                    }
                }



                //delete custom grant types that have been removed

                var exCustomGrants = existingClient.AllowedCustomGrantTypes.ToList();
                foreach (var item in exCustomGrants)
                {
                    if (!model.AllowedCustomGrantTypes.Any(x => x.Id == item.Id))
                    {
                        existingClient.AllowedCustomGrantTypes.Remove(item);
                    }
                }

                if (model.AllowedCustomGrantTypes != null && model.AllowedCustomGrantTypes.Any())
                {
                    //update and add new post redirect uris
                    foreach (var item in model.AllowedCustomGrantTypes)
                    {
                        var exCustomGrant = existingClient.AllowedCustomGrantTypes.FirstOrDefault(x => x.Id == item.Id);
                        if (exCustomGrant != null)
                        {
                            clientContext.Entry(exCustomGrant).CurrentValues.SetValues(item);
                        }
                        else
                        {
                            var newCustomGrant = new ClientCustomGrantType
                            {
                                GrantType = item.GrantType
                            };
                            existingClient.AllowedCustomGrantTypes.Add(newCustomGrant);
                        }
                    }
                }



                //delete custom grant types that have been removed

                var exSecrets = existingClient.ClientSecrets.ToList();
                foreach (var item in exSecrets)
                {
                    if (!model.ClientSecrets.Any(x => x.Id == item.Id))
                    {
                        existingClient.ClientSecrets.Remove(item);
                    }
                }

                if (model.ClientSecrets != null && model.ClientSecrets.Any())
                {
                    //update and add new post redirect uris
                    foreach (var item in model.ClientSecrets)
                    {
                        var exSecret = existingClient.ClientSecrets.FirstOrDefault(x => x.Id == item.Id);
                        if (exSecret != null)
                        {
                            exSecret.Value = exSecret.Value;
                            clientContext.Entry(exSecret).CurrentValues.SetValues(item);
                        }
                        else
                        {
                            var newSecret = new ClientSecret
                            {
                                Type        = item.Type,
                                Value       = item.Value.Sha256(),
                                Expiration  = item.Expiration,
                                Description = item.Description,
                            };
                            existingClient.ClientSecrets.Add(newSecret);
                        }
                    }
                }


                #endregion


                clientContext.SaveChanges();
                result.Exists      = true;
                result.Response    = existingClient.Id;
                result.CustomValue = existingClient.ClientName;
                return(result);
            }
            catch (Exception ex)
            {
                ErrorLogger.Log(ex);
                throw;
            }
        }