/// <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>
        /// 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);
        }