/// <summary>
        /// Create a new classification type and add it to the registry.
        /// </summary>
        public IClassificationType CreateClassificationType(string type, IEnumerable <IClassificationType> baseTypes)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (baseTypes == null)
            {
                throw new ArgumentNullException(nameof(baseTypes));
            }
            if (ClassificationTypes.ContainsKey(type))
            {
                throw new InvalidOperationException(LookUp.Strings.ClassificationAlreadyAdded);
            }

            // Use the non-canonical name for the actual type
            ClassificationTypeImpl classificationType = new ClassificationTypeImpl(type);

            foreach (var baseType in baseTypes)
            {
                classificationType.AddBaseType(baseType);
            }

            ClassificationTypes.Add(type, classificationType);

            return(classificationType);
        }
        /// <summary>
        /// Consumes all of the IClassificationTypeProvisions in the system to build the
        /// list of classification types in the system.
        /// </summary>
        private void BuildClassificationTypes(Dictionary <string, ClassificationTypeImpl> classificationTypes)
        {
            // For each content baseType provision, create an IClassificationType.
            foreach (Lazy <ClassificationTypeDefinition, IClassificationTypeDefinitionMetadata> classificationTypeDefinition in _classificationTypeDefinitions)
            {
                string classificationName = classificationTypeDefinition.Metadata.Name;

                ClassificationTypeImpl type = null;

                if (!classificationTypes.TryGetValue(classificationName, out type))
                {
                    type = new ClassificationTypeImpl(classificationName);
                    classificationTypes.Add(classificationName, type);
                }

                IEnumerable <string> baseTypes = classificationTypeDefinition.Metadata.BaseDefinition;
                if (baseTypes != null)
                {
                    ClassificationTypeImpl baseType = null;

                    foreach (string baseClassificationType in baseTypes)
                    {
                        if (!classificationTypes.TryGetValue(baseClassificationType, out baseType))
                        {
                            baseType = new ClassificationTypeImpl(baseClassificationType);
                            classificationTypes.Add(baseClassificationType, baseType);
                        }

                        type.AddBaseType(baseType);
                    }
                }
            }
        }
        public IClassificationType GetClassificationType(string type)
        {
            ClassificationTypeImpl classificationType = null;

            this.ClassificationTypes.TryGetValue(type, out classificationType);

            return(classificationType);
        }
        /// <summary>
        /// Builds a new transient classification type based on a set of actual base
        /// types.
        ///
        /// With multiple projection buffers, it is possible to have a transient classification
        /// type with transient types as parents.
        /// </summary>
        /// <param name="baseTypes"></param>
        /// <returns></returns>
        private IClassificationType BuildTransientClassificationType(IEnumerable <IClassificationType> baseTypes)
        {
            // Lazily init
            if (_transientClassificationTypes == null)
            {
                _transientClassificationTypes = new Dictionary <string, ClassificationTypeImpl>(StringComparer.OrdinalIgnoreCase);
            }

            List <IClassificationType> sortedBaseTypes = new List <IClassificationType>(baseTypes);

            sortedBaseTypes.Sort(delegate(IClassificationType a, IClassificationType b)
                                 { return(string.CompareOrdinal(a.Classification, b.Classification)); });

            // Build the transient name
            StringBuilder sb = new StringBuilder();

            foreach (IClassificationType type in sortedBaseTypes)
            {
                sb.Append(type.Classification);
                sb.Append(" - ");
            }

            // Append "(transient)" onto the name.
            sb.Append(this.TransientClassificationType.Classification);

            // Look for a cached type
            ClassificationTypeImpl transientType;

            if (!_transientClassificationTypes.TryGetValue(sb.ToString(), out transientType))
            {
                // Didn't find a cached type, so create a new one
                transientType = new ClassificationTypeImpl(sb.ToString());

                foreach (IClassificationType type in sortedBaseTypes)
                {
                    transientType.AddBaseType(type);
                }

                // Add in the transient type as a base type
                transientType.AddBaseType(TransientClassificationType);

                // Cache this type so it doesn't need to be created again.
                _transientClassificationTypes[transientType.Classification] = transientType;
            }

            return(transientType);
        }