public async Task <IdentityResult> AddSecretToClientAsync(Neo4jIdentityServer4Client client,
                                                                  Neo4jIdentityServer4ClientSecret secret,
                                                                  CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();
            client.ThrowIfNull(nameof(client));
            secret.ThrowIfNull(nameof(secret));
            try
            {
                var cypher = $@"
                MATCH (c:{IdSrv4Client} {{ClientId: $p0}})
                CREATE UNIQUE 
                    (c)-[:{Neo4jConstants.Relationships.HasSecret}]->
                    (s:{IdSrv4ClientSecret} {"$p1".AsMapForNoNull(secret)})";

                var result = await Session.RunAsync(cypher, Params.Create(client.ClientId, secret));

                await RaiseClientChangeEventAsync(client);

                return(IdentityResult.Success);
            }
            catch (ClientException ex)
            {
                return(ex.ToIdentityResult());
            }
        }
        public async Task <IdentityResult> DeleteSecretAsync(
            Neo4jIdentityServer4Client client,
            Neo4jIdentityServer4ClientSecret secret,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();
            client.ThrowIfNull(nameof(client));
            secret.ThrowIfNull(nameof(secret));
            try
            {
                var cypher = $@"
                MATCH (c:{IdSrv4Client})-[:{Neo4jConstants.Relationships.HasSecret}]->(s:{IdSrv4ClientSecret})
                WHERE c.ClientId = $p0 AND s.Value = $p1
                DETACH DELETE s";

                await Session.RunAsync(cypher,
                                       Params.Create(
                                           client.ClientId,
                                           secret.Value));
                await RaiseClientChangeEventAsync(client);

                return(IdentityResult.Success);
            }
            catch (ClientException ex)
            {
                return(ex.ToIdentityResult());
            }
        }
        public async Task <Neo4jIdentityServer4ClientSecret> FindSecretAsync(Neo4jIdentityServer4Client client,
                                                                             Neo4jIdentityServer4ClientSecret secret,
                                                                             CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();
            client.ThrowIfNull(nameof(client));
            secret.ThrowIfNull(nameof(secret));

            var cypher = $@"
                MATCH (c:{IdSrv4Client})-[:{Neo4jConstants.Relationships.HasSecret}]->(s:{IdSrv4ClientSecret})
                WHERE c.ClientId = $p0 AND s.Value = $p1
                RETURN s{{ .* }}";

            var result = await Session.RunAsync(cypher,
                                                Params.Create(
                                                    client.ClientId,
                                                    secret.Value));

            var foundRecord =
                await result.SingleOrDefaultAsync(r => r.MapTo <Neo4jIdentityServer4ClientSecret>("s"));

            return(foundRecord);
        }