// LUCENENET specific - removed this class and replaced it with abstract factories
// DefaultCodecFactory, DefaultDocValuesFormatFactory, and DefaultPostingsFormatFactory
// and their common base class, NamedServiceFactory<TService>.
// The factories have a more efficient default scanning implementation and make
// it possible to use an external dependency injection container to supply the constructed
// codecs without any constraints on the constructor.

//using Lucene.Net.Support;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Reflection;

//namespace Lucene.Net.Util
//{
//    /*
//     * Licensed to the Apache Software Foundation (ASF) under one or more
//     * contributor license agreements.  See the NOTICE file distributed with
//     * this work for additional information regarding copyright ownership.
//     * The ASF licenses this file to You under the Apache License, Version 2.0
//     * (the "License"); you may not use this file except in compliance with
//     * the License.  You may obtain a copy of the License at
//     *
//     *     http://www.apache.org/licenses/LICENSE-2.0
//     *
//     * Unless required by applicable law or agreed to in writing, software
//     * distributed under the License is distributed on an "AS IS" BASIS,
//     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//     * See the License for the specific language governing permissions and
//     * limitations under the License.
//     */

//    /// <summary>
//    /// Helper class for loading named SPIs from classpath (e.g. Codec, PostingsFormat).
//    /// @lucene.internal
//    /// </summary>
//    public sealed class NamedSPILoader<S> : IEnumerable<S> where S : NamedSPILoader.INamedSPI
//    {
//        private volatile IDictionary<string, S> services = Collections.EmptyMap<string, S>();
//        private readonly Type clazz;

//        public NamedSPILoader(Type clazz)
//        {
//            this.clazz = clazz;
//            // if clazz' classloader is not a parent of the given one, we scan clazz's classloader, too:

//            Reload();
//        }

//        /// <summary>
//        /// Reloads the internal SPI list from the given <seealso cref="ClassLoader"/>.
//        /// Changes to the service list are visible after the method ends, all
//        /// iterators (<seealso cref="#iterator()"/>,...) stay consistent.
//        ///
//        /// <p><b>NOTE:</b> Only new service providers are added, existing ones are
//        /// never removed or replaced.
//        ///
//        /// <p><em>this method is expensive and should only be called for discovery
//        /// of new service providers on the given classpath/classloader!</em>
//        /// </summary>
//        public void Reload()
//        {
//            lock (this)
//            {
//                IDictionary<string, S> services = new Dictionary<string, S>(this.services);
//                SPIClassIterator<S> loader = SPIClassIterator<S>.Get();

//                // Ensure there is a default constructor (the SPIClassIterator contains types that don't)
//                foreach (Type c in loader.Where(t => t.GetConstructor(Type.EmptyTypes) != null))
//                {
//                    try
//                    {
//                        S service = (S)Activator.CreateInstance(c);
//                        string name = service.Name;
//                        // only add the first one for each name, later services will be ignored
//                        // this allows to place services before others in classpath to make
//                        // them used instead of others
//                        if (!services.ContainsKey(name))
//                        {
//                            CheckServiceName(name);
//                            services[name] = service;
//                        }
//                    }
//                    catch (Exception e)
//                    {
//                        throw new InvalidOperationException("Cannot instantiate SPI class: " + c.Name, e);
//                    }
//                }
//                this.services = Collections.UnmodifiableMap(services);
//            }
//        }

//        /// <summary>
//        /// Validates that a service name meets the requirements of <seealso cref="INamedSPI"/>
//        /// </summary>
//        public static void CheckServiceName(string name)
//        {
//            // based on harmony charset.java
//            if (name.Length >= 128)
//            {
//                throw new ArgumentException("Illegal service name: '" + name + "' is too long (must be < 128 chars).");
//            }
//            for (int i = 0, len = name.Length; i < len; i++)
//            {
//                char c = name[i];
//                if (!IsLetterOrDigit(c))
//                {
//                    throw new ArgumentException("Illegal service name: '" + name + "' must be simple ascii alphanumeric.");
//                }
//            }
//        }

//        /// <summary>
//        /// Checks whether a character is a letter or digit (ascii) which are defined in the spec.
//        /// </summary>
//        private static bool IsLetterOrDigit(char c)
//        {
//            return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9');
//        }

//        public S Lookup(string name)
//        {
//            S service;
//            if (services.TryGetValue(name, out service))
//            {
//                return service;
//            }
//            throw new ArgumentException("A SPI class of type " + clazz.Name + " with name '" + name + "' does not exist. " + "You need to add the corresponding JAR file supporting this SPI to your classpath." + "The current classpath supports the following names: " + AvailableServices());
//        }

//        public ISet<string> AvailableServices()
//        {
//            return new HashSet<string>(services.Keys);
//        }

//        public IEnumerator<S> GetEnumerator()
//        {
//            return services.Values.GetEnumerator();
//        }

//        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
//        {
//            return GetEnumerator();
//        }
//    }

//    public class NamedSPILoader
//    {
//        private NamedSPILoader() { } // prevent direct creation

//        /// <summary>
//        /// Interface to support <seealso cref="NamedSPILoader#lookup(String)"/> by name.
//        /// <p>
//        /// Names must be all ascii alphanumeric, and less than 128 characters in length.
//        /// </summary>
//        public interface INamedSPI
//        {
//            string Name { get; }
//        }
//    }
//}