/// <summary>
        /// Resolves the applicable <see cref="OrganizationalParticipant" />s needed to edit a particulat
        /// <see cref="CDP4Common.DTO.Thing" />
        /// </summary>
        /// <param name="transaction">
        /// The transaction object.
        /// </param>
        /// <param name="iteration">The <see cref="Iteration" /></param>
        /// <param name="thing">The <see cref="CDP4Common.DTO.Thing" /> to compute permissions for.</param>
        /// <param name="organizationalParticipantIid">The Iid of OrganizationalParticipant to validate</param>
        /// <param name="partition">
        /// The database partition (schema) where the requested resource is stored.
        /// </param>
        /// <returns>
        /// The list of the applicable <see cref="OrganizationalParticipant" />s needed to edit a particulat
        /// <see cref="CDP4Common.DTO.Thing" />
        /// </returns>
        public bool ResolveApplicableOrganizationalParticipations(NpgsqlTransaction transaction, string partition, Iteration iteration, Thing thing, Guid organizationalParticipantIid)
        {
            var securityContext = new RequestSecurityContext {
                ContainerReadAllowed = true
            };

            this.ResolveElementDefinitionTree(transaction, partition, iteration, organizationalParticipantIid, securityContext, out var elementDefinitions, out var relevantOpenDefinitions, out var fullTree);

            // only perform usage checks if certain classkinds are checked
            if (thing.ClassKind == ClassKind.ElementUsage ||
                thing.ClassKind == ClassKind.ParameterOverride ||
                thing.ClassKind == ClassKind.ParameterOverrideValueSet ||
                thing.ClassKind == ClassKind.Definition ||
                thing.ClassKind == ClassKind.Alias ||
                thing.ClassKind == ClassKind.HyperLink ||
                thing.ClassKind == ClassKind.Citation)
            {
                // add also element usages of allowed EDs and their contained items to list
                var elementUsages = this.ElementUsageService.Get(transaction, partition, elementDefinitions.SelectMany(ed => ed.ContainedElement), securityContext).Cast <ElementUsage>();

                // select relevant
                var relevatElementUsages = elementUsages.Where(eu => relevantOpenDefinitions.Select(ed => ed.Iid).Contains(eu.ElementDefinition));

                // get subtrees
                var relevantUsageSubtrees = this.ElementUsageService.GetDeep(transaction, partition, relevatElementUsages.Select(eu => eu.Iid), securityContext);

                //concat to ed trees
                fullTree = fullTree.Concat(relevantUsageSubtrees);
            }

            // if the thing we are checking exists in the trees of allowed EDs, allow it to pass
            var result = fullTree.FirstOrDefault(t => t.Iid.Equals(thing.Iid)) != null;

            return(result);
        }
        /// <summary>
        /// Resolves the ElementDefinition tree
        /// </summary>
        /// <param name="transaction">
        /// The transaction object.
        /// </param>
        /// <param name="iteration">The <see cref="Iteration" /></param>
        /// =
        /// <param name="organizationalParticipantIid">The Iid of OrganizationalParticipant to validate</param>
        /// <param name="partition">
        /// The database partition (schema) where the requested resource is stored.
        /// </param>
        /// <param name="securityContext">The security context</param>
        /// <param name="elementDefinitions">The list of all element definitions</param>
        /// <param name="relevantOpenDefinitions">
        /// The list of element definitions that are allowed to be seen by the organizational
        /// participant
        /// </param>
        /// <param name="fullTree">The full tree of allowed element definitions</param>
        private void ResolveElementDefinitionTree(NpgsqlTransaction transaction, string partition, Iteration iteration, Guid organizationalParticipantIid, RequestSecurityContext securityContext, out List <ElementDefinition> elementDefinitions, out List <ElementDefinition> relevantOpenDefinitions, out IEnumerable <Thing> fullTree)
        {
            // get all ED's shallow to determine relevant
            elementDefinitions = this.ElementDefinitionService.Get(transaction, partition, iteration.Element, securityContext).Cast <ElementDefinition>().ToList();

            // given a participation, select only allowed EDs
            relevantOpenDefinitions = elementDefinitions.Where(ed => ed.OrganizationalParticipant.Contains(organizationalParticipantIid)).ToList();

            // get deep expansions only of relevant Element Definitions
            fullTree = this.ElementDefinitionService.GetDeep(transaction, partition, relevantOpenDefinitions.Select(ed => ed.Iid), securityContext);
        }