1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing System;
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing System.Collections.Generic;
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing System.Text;
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Taken from Mono sources, changed to work on C# 2.0 compilers
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Enumerable.cs
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Authors:
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//  Marek Safar (marek.safar@gmail.com)
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//  Antonello Provenzano  <antonello@deveel.com>
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//  Alejandro Serrano "Serras" (trupill@yahoo.es)
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//  Jb Evain (jbevain@novell.com)
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Permission is hereby granted, free of charge, to any person obtaining
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// a copy of this software and associated documentation files (the
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// "Software"), to deal in the Software without restriction, including
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// without limitation the rights to use, copy, modify, merge, publish,
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// distribute, sublicense, and/or sell copies of the Software, and to
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// permit persons to whom the Software is furnished to do so, subject to
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// the following conditions:
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// The above copyright notice and this permission notice shall be
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// included in all copies or substantial portions of the Software.
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// precious: http://www.hookedonlinq.com
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic delegate TResult Func<TResult>();
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic delegate TResult Func<T, TResult>(T arg1);
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace Antlr.Runtime.JavaExtensions {
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    static class EnumerableExtensions {
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region Average
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static double Average(IEnumerable<int> source) {
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return Average<int, long, double>(source, delegate(long a, int b) { return a + b; }, delegate(long a, long b) { return (double)a / (double)b; });
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static TResult Average<TElement, TAggregate, TResult>(IEnumerable<TElement> source,
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            where TElement : struct
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            where TAggregate : struct
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            where TResult : struct {
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.Source(source);
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            var total = default(TAggregate);
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            long counter = 0;
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (var element in source) {
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                total = func(total, element);
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ++counter;
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (counter == 0)
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new InvalidOperationException();
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return result(total, counter);
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static double Average(IEnumerable<double> source) {
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return Average<double, double, double>(source, delegate(double a, double b) { return a + b; }, delegate(double a, long b) { return a / b; });
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region Contains
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static bool Contains<TSource>(IEnumerable<TSource> source, TSource value) {
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            var collection = source as ICollection<TSource>;
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (collection != null)
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return collection.Contains(value);
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return Contains<TSource>(source, value, null);
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static bool Contains<TSource>(IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer) {
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.Source(source);
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (comparer == null)
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                comparer = EqualityComparer<TSource>.Default;
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (var element in source)
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (comparer.Equals(element, value))
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    return true;
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return false;
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region DefaultIfEmpty
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static IEnumerable<TSource> DefaultIfEmpty<TSource>(IEnumerable<TSource> source) {
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return DefaultIfEmpty(source, default(TSource));
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static IEnumerable<TSource> DefaultIfEmpty<TSource>(IEnumerable<TSource> source, TSource defaultValue) {
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.Source(source);
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return CreateDefaultIfEmptyIterator(source, defaultValue);
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource>(IEnumerable<TSource> source, TSource defaultValue) {
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            bool empty = true;
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (TSource item in source) {
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                empty = false;
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                yield return item;
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (empty)
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                yield return defaultValue;
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region Max
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static int Max(IEnumerable<int> source) {
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.Source(source);
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return Iterate(source, int.MinValue, delegate(int a, int b){return Math.Max(a, b);});
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static U Iterate<T, U>(IEnumerable<T> source, U initValue, Func<T, U, U> selector) {
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            bool empty = true;
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (var element in source) {
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                initValue = selector(element, initValue);
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                empty = false;
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (empty)
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new InvalidOperationException();
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return initValue;
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region Min
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static int Min(IEnumerable<int> source) {
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.Source(source);
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return Iterate(source, int.MaxValue, delegate(int a, int b) { return Math.Min(a, b); });
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region Select
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static IEnumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector) {
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.SourceAndSelector(source, selector);
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return CreateSelectIterator(source, selector);
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static IEnumerable<TResult> CreateSelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector) {
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (var element in source)
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                yield return selector(element);
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static IEnumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.SourceAndSelector(source, selector);
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return CreateSelectIterator(source, selector);
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static IEnumerable<TResult> CreateSelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int counter = 0;
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (TSource element in source) {
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                yield return selector(element, counter);
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                counter++;
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region SelectMany
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(IEnumerable<TSource> source,
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector) {
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.SourceAndCollectionSelectors(source, collectionSelector, selector);
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return CreateSelectManyIterator(source, collectionSelector, selector);
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static IEnumerable<TResult> SelectMany<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector) {
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.SourceAndSelector(source, selector);
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return CreateSelectManyIterator(source, selector);
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult>(IEnumerable<TSource> source,
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector) {
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int counter = 0;
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (TSource element in source)
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                foreach (TCollection collection in collectionSelector(element, counter++))
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    yield return selector(element, collection);
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector) {
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int counter = 0;
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (TSource element in source) {
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                foreach (TResult item in selector(element, counter))
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    yield return item;
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                counter++;
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region Sum
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static int Sum(IEnumerable<int> source) {
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.Source(source);
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return Sum<int, int>(source, delegate(int a, int b) { return checked(a + b); });
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static TR Sum<TA, TR>(IEnumerable<TA> source, Func<TR, TA, TR> selector) {
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            TR total = default(TR);
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (var element in source) {
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                total = selector(total, element);
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return total;
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region Take
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static IEnumerable<TSource> Take<TSource>(IEnumerable<TSource> source, int count) {
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.Source(source);
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return CreateTakeIterator(source, count);
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        static IEnumerable<TSource> CreateTakeIterator<TSource>(IEnumerable<TSource> source, int count) {
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (count <= 0)
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                yield break;
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int counter = 0;
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (TSource element in source) {
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                yield return element;
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (++counter == count)
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    yield break;
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #region ToArray
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static TSource[] ToArray<TSource>(IEnumerable<TSource> source) {
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Check.Source(source);
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            var collection = source as ICollection<TSource>;
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (collection != null) {
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                var array = new TSource[collection.Count];
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                collection.CopyTo(array, 0);
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return array;
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return new List<TSource>(source).ToArray();
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #endregion
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
287