public AuthoriseReferenceStrategyInfo Locate(string typeName1, string propertyName1, string typeName2, string propertyName2)
        {
            AuthoriseReferenceStrategyInfo output = null;

            using (LogGroup logGroup = LogGroup.StartDebug("Locating an authorise reference strategy."))
            {
                foreach (AuthoriseReferenceStrategyInfo strategy in LocateAll(typeName1, propertyName1, typeName2, propertyName2))
                {
                    LogWriter.Debug("Found strategy: " + strategy.GetType().FullName);

                    // If the output is null
                    if (output == null
                        // Or the current strategy is more specific than the output
                        || IsMoreSpecific(strategy, output))
                    {
                        LogWriter.Debug("Strategy is more specific. Using.");

                        output = strategy;
                    }
                    else
                    {
                        LogWriter.Debug("Strategy is more general. Skipping.");
                    }
                }

                LogWriter.Debug("Output: " + (output == null ? "[null]" : output.GetType().FullName));
            }

            return(output);
        }
        public AuthoriseReferenceStrategyInfo[] LocateAll(string typeName1, string propertyName1, string typeName2, string propertyName2)
        {
            List <AuthoriseReferenceStrategyInfo> list = new List <AuthoriseReferenceStrategyInfo>();

            using (LogGroup logGroup = LogGroup.StartDebug("Locating all potentially matching authorise reference strategies."))
            {
                LogWriter.Debug("Total strategies available: " + Strategies.Count);

                foreach (StrategyInfo s in Strategies)
                {
                    if (s is AuthoriseReferenceStrategyInfo)
                    {
                        using (LogGroup logGroup2 = LogGroup.StartDebug("Checking authorise reference strategy: " + s.GetType().Name))
                        {
                            AuthoriseReferenceStrategyInfo strategy = (AuthoriseReferenceStrategyInfo)s;

                            LogWriter.Debug("Strategy type name 1: " + strategy.TypeName);
                            LogWriter.Debug("Strategy type name 2: " + strategy.ReferencedTypeName);

                            if (EntityState.IsType(typeName1) && EntityState.IsType(typeName2))
                            {
                                Type type1 = EntityState.GetType(typeName1);
                                Type type2 = EntityState.GetType(typeName2);

                                if (type1 != null && type2 != null)
                                {
                                    bool matches1 = TypesMatch(typeName1, strategy.TypeName);
                                    bool matches2 = TypesMatch(typeName2, strategy.ReferencedTypeName);

                                    bool matchesProperty1 = PropertiesMatch(propertyName1, strategy.ReferenceProperty);
                                    bool matchesProperty2 = PropertiesMatch(propertyName2, strategy.MirrorProperty);

                                    LogWriter.Debug("Matches type 1: " + matches1.ToString());
                                    LogWriter.Debug("Matches type 2: " + matches2.ToString());

                                    LogWriter.Debug("Matches property 1: " + matchesProperty1.ToString());
                                    LogWriter.Debug("Matches property 2: " + matchesProperty2.ToString());

                                    if (matches1 && matches2 &&
                                        matchesProperty1 && matchesProperty2)
                                    {
                                        LogWriter.Debug("Both types and properties match. Using.");
                                        list.Add(strategy);
                                    }
                                    else
                                    {
                                        LogWriter.Debug("Types or properties don't match. Skipping.");
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(list.ToArray());
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="specificStrategy"></param>
        /// <param name="generalStrategy"></param>
        /// <returns></returns>
        public bool IsMoreSpecific(AuthoriseReferenceStrategyInfo specificStrategy, AuthoriseReferenceStrategyInfo generalStrategy)
        {
            bool isMoreSpecific = false;

            using (LogGroup logGroup = LogGroup.StartDebug("Checking whether the '" + specificStrategy.StrategyType + "' strategy is more specific than the '" + generalStrategy.StrategyType + "' strategy."))
            {
                bool type1IsMoreSpecific = IsMoreSpecific(specificStrategy.Type, generalStrategy.Type);
                bool type2IsMoreSpecific = IsMoreSpecific(specificStrategy.ReferencedType, generalStrategy.ReferencedType);

                bool type1IsMoreGeneral = IsMoreGeneral(specificStrategy.Type, generalStrategy.Type);
                bool type2IsMoreGeneral = IsMoreGeneral(specificStrategy.ReferencedType, generalStrategy.ReferencedType);

                // If either type is more specific AND the other type is NOT more general
                isMoreSpecific = (type1IsMoreSpecific && !type2IsMoreGeneral) ||
                                 (type2IsMoreSpecific && !type1IsMoreGeneral);

                LogWriter.Debug("Is more specific: " + isMoreSpecific);
            }
            return(isMoreSpecific);
        }