public static AbstractType[] FilterFromMostToLeastSpecialized(
            IEnumerable <AbstractType> templateOverloads,
            ResolutionContext ctxt)
        {
            if (templateOverloads == null)
            {
                return(null);
            }

            var so = new SpecializationOrdering {
                ctxt = ctxt
            };

            /*
             * Note: If there are functions that are specialized equally, like
             * void foo(T) (T t) {} and
             * void foo(T) (T t, int a) {},
             * both functions have to be returned - because foo!string matches both overloads.
             * Later on, in the parameter-argument-comparison, these overloads will be filtered a second time - only then,
             * two overloads would be illegal.
             */
            var lastEquallySpecializedOverloads = new List <AbstractType>();
            var en = templateOverloads.GetEnumerator();

            if (!en.MoveNext())
            {
                return(null);
            }
            var currentlyMostSpecialized = en.Current;

            lastEquallySpecializedOverloads.Add(currentlyMostSpecialized);

            while (en.MoveNext())
            {
                var evenMoreSpecialized = so.GetTheMoreSpecialized(currentlyMostSpecialized, en.Current);

                if (evenMoreSpecialized == null)
                {
                    lastEquallySpecializedOverloads.Add(en.Current);
                }
                else
                {
                    currentlyMostSpecialized = evenMoreSpecialized;

                    lastEquallySpecializedOverloads.Clear();
                    lastEquallySpecializedOverloads.Add(currentlyMostSpecialized);
                }
            }

            return(lastEquallySpecializedOverloads.ToArray());
        }
		public static AbstractType[] FilterFromMostToLeastSpecialized(
			IEnumerable<AbstractType> templateOverloads,
			ResolutionContext ctxt)
		{
			if (templateOverloads == null)
				return null;

			var so = new SpecializationOrdering { ctxt = ctxt };

			/*
			 * Note: If there are functions that are specialized equally, like
			 * void foo(T) (T t) {} and
			 * void foo(T) (T t, int a) {},
			 * both functions have to be returned - because foo!string matches both overloads.
			 * Later on, in the parameter-argument-comparison, these overloads will be filtered a second time - only then, 
			 * two overloads would be illegal.
			 */
			var lastEquallySpecializedOverloads = new List<AbstractType>();
			var en = templateOverloads.GetEnumerator();
			if (!en.MoveNext())
				return null;
			var currentlyMostSpecialized = en.Current;
			lastEquallySpecializedOverloads.Add(currentlyMostSpecialized);

			while(en.MoveNext())
			{
				var evenMoreSpecialized = so.GetTheMoreSpecialized(currentlyMostSpecialized, en.Current);

				if (evenMoreSpecialized == null)
					lastEquallySpecializedOverloads.Add(en.Current);
				else
				{
					currentlyMostSpecialized = evenMoreSpecialized;

					lastEquallySpecializedOverloads.Clear();
					lastEquallySpecializedOverloads.Add(currentlyMostSpecialized);
				}
			}

			return lastEquallySpecializedOverloads.ToArray();
		}