/// <summary>
        /// Gets meta-features on the opposite side of relationship.
        /// </summary>
        /// <param name="metaFeature">MetaFeature end of relationship.</param>
        /// <param name="role">The role of returned meta-features with regards to the given meta-feature.</param>
        /// <returns>List of opposite role players.</returns>
        public IList <MetaFeature> GetRolePlayers(MetaFeature metaFeature, MetaRelationshipKind role)
        {
            if (metaFeature == null)
            {
                throw new ArgumentNullException("feature");
            }

            if (this.m_relationshipsDirty)
            {
                RebuildRelationships();
            }

            Dictionary <MetaFeature, List <MetaFeature> > s1;

            if (!m_relationships.TryGetValue(role, out s1))
            {
                return(new List <MetaFeature>());
            }

            List <MetaFeature> result;

            if (!s1.TryGetValue(metaFeature, out result))
            {
                return(new List <MetaFeature>());
            }

            return(result);
        }
        private void AddOneSideRelationship(MetaFeature feature1, MetaRelationshipKind kind, MetaFeature feature2)
        {
            Dictionary <MetaFeature, List <MetaFeature> > s1;

            if (!m_relationships.TryGetValue(kind, out s1))
            {
                s1 = new Dictionary <MetaFeature, List <MetaFeature> >();
                m_relationships[kind] = s1;
            }
            List <MetaFeature> s2;

            if (!s1.TryGetValue(feature1, out s2))
            {
                s2           = new List <MetaFeature>();
                s1[feature1] = s2;
            }
            s2.Add(feature2);
        }
        private void AddMetaRelationship(MetaFeature feature1, MetaRelationshipKind kind, MetaFeature feature2)
        {
            if (feature1 == null)
            {
                throw new ArgumentNullException("feature1");
            }
            if (feature2 == null)
            {
                throw new ArgumentNullException("feature2");
            }
            if (feature1 == feature2)
            {
                throw new InvalidOperationException();
            }

            AddOneSideRelationship(feature1, kind, feature2);
            switch (kind)
            {
            case MetaRelationshipKind.Child:
                kind = MetaRelationshipKind.Parent;
                break;

            case MetaRelationshipKind.Dependants:
                kind = MetaRelationshipKind.Depends;
                break;

            case MetaRelationshipKind.Depends:
                kind = MetaRelationshipKind.Dependants;
                break;

            case MetaRelationshipKind.Parent:
                kind = MetaRelationshipKind.Child;
                break;

            default:
                throw new InvalidOperationException();
            }
            AddOneSideRelationship(feature2, kind, feature1);
        }