/// <inheritdoc />
        public IEnumerable <char> Process(char input)
        {
            if (this.inputPreprocessors.Count == 0)
            {
                yield return(input);

                yield break;
            }

            Queue <PreprocessedInput> processQueue = queuePool.Create();
            Queue <PreprocessedInput> outputQueue  = queuePool.Create();

            processQueue.Enqueue(input);

            foreach (var preprocessor in this.inputPreprocessors)
            {
                while (processQueue.Count > 0)
                {
                    var toProcess = processQueue.Dequeue();
                    if (toProcess.Replacement != null)
                    {
                        foreach (var toProcessChar in toProcess.Replacement)
                        {
                            outputQueue.Enqueue(preprocessor.Preprocess(toProcessChar));
                        }
                    }
                    else
                    {
                        outputQueue.Enqueue(preprocessor.Preprocess(toProcess.Value));
                    }
                }

                outputQueue = Interlocked.Exchange(ref processQueue, outputQueue);
            }

            while (processQueue.Count > 0)
            {
                var toReturn = processQueue.Dequeue();
                if (toReturn.Replacement != null)
                {
                    foreach (var letter in toReturn.Replacement)
                    {
                        yield return(letter);
                    }
                }
                else
                {
                    yield return(toReturn.Value);
                }
            }

            queuePool.Return(processQueue);
            queuePool.Return(outputQueue);
        }