You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2019/08/07 22:26:38 UTC

[lucenenet] 41/42: SWEEP: Ensure all enumerators are disposed of properly (except in some cases where enumerators are set to field variables, see LUCENENET-611)

This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit e12cde4c49bf5665540f29322f70631491133569
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Wed Aug 7 14:21:23 2019 +0700

    SWEEP: Ensure all enumerators are disposed of properly (except in some cases where enumerators are set to field variables, see LUCENENET-611)
---
 .../Analysis/Nl/DutchAnalyzer.cs                   |  14 +-
 .../Analysis/Shingle/ShingleFilter.cs              |  36 +--
 .../Analysis/Synonym/SlowSynonymMap.cs             |  54 ++---
 .../Analysis/Util/CharArrayMap.cs                  |  86 +++----
 .../Analysis/Util/CharArraySet.cs                  |   8 +-
 .../Egothor.Stemmer/Gener.cs                       |   6 +-
 .../Egothor.Stemmer/Lift.cs                        |   4 +-
 .../Egothor.Stemmer/Optimizer.cs                   |   8 +-
 .../Egothor.Stemmer/Reduce.cs                      |  21 +-
 .../Egothor.Stemmer/Row.cs                         |  23 +-
 .../Support/Sax/Helpers/NamespaceSupport.cs        |   1 +
 .../Memory/MemoryDocValuesConsumer.cs              |   3 +-
 .../SimpleText/SimpleTextDocValuesWriter.cs        |  69 +++---
 .../Taxonomy/WriterCache/CompactLabelToOrdinal.cs  |  11 +-
 .../VectorHighlight/BaseFragListBuilder.cs         |  93 ++++----
 .../VectorHighlight/BaseFragmentsBuilder.cs        |  54 ++---
 .../VectorHighlight/FastVectorHighlighter.cs       |   5 +-
 .../VectorHighlight/FieldPhraseList.cs             | 167 ++++++++------
 .../VectorHighlight/SingleFragListBuilder.cs       |  22 +-
 src/Lucene.Net.Memory/MemoryIndex.cs               |   8 +-
 .../Flexible/Core/Nodes/OrQueryNode.cs             |   4 +-
 .../Processors/RemoveDeletedQueryNodesProcessor.cs |   4 +-
 .../Standard/Parser/StandardSyntaxParser.cs        |  25 ++-
 .../Queries/FuzzyLikeThisQuery.cs                  |   7 +-
 .../Codecs/Asserting/AssertingDocValuesFormat.cs   |  97 ++++----
 .../Codecs/MissingOrdRemapper.cs                   |  21 +-
 .../Index/FieldFilterAtomicReader.cs               |   3 +-
 .../JavaCompatibility/SystemTypesHelpers.cs        |  10 +-
 .../Store/MockDirectoryWrapper.cs                  | 163 +++++++-------
 .../Util/LuceneTestCase.cs                         |  33 +--
 src/Lucene.Net/Index/CoalescedUpdates.cs           |   1 +
 src/Lucene.Net/Index/IndexWriter.cs                |   7 +-
 src/Lucene.Net/Search/BooleanQuery.cs              | 115 +++++-----
 src/Lucene.Net/Search/MultiPhraseQuery.cs          |   8 +-
 src/Lucene.Net/Search/Payloads/PayloadNearQuery.cs |   4 +-
 src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs  |   5 +-
 src/Lucene.Net/Search/Spans/SpanNearQuery.cs       |   4 +-
 src/Lucene.Net/Search/Spans/SpanOrQuery.cs         |   9 +-
 .../Search/Spans/SpanPayloadCheckQuery.cs          |  18 +-
 src/Lucene.Net/Support/HashMap.cs                  |  70 +++---
 src/Lucene.Net/Support/TreeSet.cs                  | 246 +++++++++++----------
 src/Lucene.Net/Util/AttributeSource.cs             |  16 +-
 src/Lucene.Net/Util/Automaton/BasicOperations.cs   |   5 +-
 .../Util/Automaton/LevenshteinAutomata.cs          |  10 +-
 src/Lucene.Net/Util/Automaton/SpecialOperations.cs |   8 +-
 src/Lucene.Net/Util/CloseableThreadLocal.cs        |   3 +-
 src/Lucene.Net/Util/MergedIterator.cs              |   5 +-
 src/Lucene.Net/Util/WAH8DocIdSet.cs                |   9 +-
 .../tools/lucene-cli/SourceCode/ConsolePager.cs    |   2 +-
 49 files changed, 835 insertions(+), 770 deletions(-)

diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Nl/DutchAnalyzer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Nl/DutchAnalyzer.cs
index 07ce34a..7352d2c 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Nl/DutchAnalyzer.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Nl/DutchAnalyzer.cs
@@ -168,13 +168,15 @@ namespace Lucene.Net.Analysis.Nl
                 this.origStemdict = null;
                 // we don't need to ignore case here since we lowercase in this analyzer anyway
                 StemmerOverrideFilter.Builder builder = new StemmerOverrideFilter.Builder(false);
-                CharArrayMap<string>.EntryIterator iter = (CharArrayMap<string>.EntryIterator)stemOverrideDict.EntrySet().GetEnumerator();
-                CharsRef spare = new CharsRef();
-                while (iter.HasNext)
+                using (CharArrayMap<string>.EntryIterator iter = (CharArrayMap<string>.EntryIterator)stemOverrideDict.EntrySet().GetEnumerator())
                 {
-                    char[] nextKey = iter.NextKey();
-                    spare.CopyChars(nextKey, 0, nextKey.Length);
-                    builder.Add(new string(spare.Chars), iter.CurrentValue);
+                    CharsRef spare = new CharsRef();
+                    while (iter.HasNext)
+                    {
+                        char[] nextKey = iter.NextKey();
+                        spare.CopyChars(nextKey, 0, nextKey.Length);
+                        builder.Add(new string(spare.Chars), iter.CurrentValue);
+                    }
                 }
                 try
                 {
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Shingle/ShingleFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Shingle/ShingleFilter.cs
index 609a50b..709474e 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Shingle/ShingleFilter.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Shingle/ShingleFilter.cs
@@ -326,29 +326,31 @@ namespace Lucene.Net.Analysis.Shingle
             {
                 bool isAllFiller = true;
                 InputWindowToken nextToken = null;
-                IEnumerator<InputWindowToken> iter = inputWindow.GetEnumerator();
-                for (int gramNum = 1; iter.MoveNext() && builtGramSize < gramSize.Value; ++gramNum)
+                using (IEnumerator<InputWindowToken> iter = inputWindow.GetEnumerator())
                 {
-                    nextToken = iter.Current;
-                    if (builtGramSize < gramNum)
+                    for (int gramNum = 1; iter.MoveNext() && builtGramSize < gramSize.Value; ++gramNum)
                     {
-                        if (builtGramSize > 0)
+                        nextToken = iter.Current;
+                        if (builtGramSize < gramNum)
                         {
-                            gramBuilder.Append(tokenSeparator);
+                            if (builtGramSize > 0)
+                            {
+                                gramBuilder.Append(tokenSeparator);
+                            }
+                            gramBuilder.Append(nextToken.termAtt.Buffer, 0, nextToken.termAtt.Length);
+                            ++builtGramSize;
                         }
-                        gramBuilder.Append(nextToken.termAtt.Buffer, 0, nextToken.termAtt.Length);
-                        ++builtGramSize;
-                    }
-                    if (isAllFiller && nextToken.isFiller)
-                    {
-                        if (gramNum == gramSize.Value)
+                        if (isAllFiller && nextToken.isFiller)
                         {
-                            gramSize.Advance();
+                            if (gramNum == gramSize.Value)
+                            {
+                                gramSize.Advance();
+                            }
+                        }
+                        else
+                        {
+                            isAllFiller = false;
                         }
-                    }
-                    else
-                    {
-                        isAllFiller = false;
                     }
                 }
                 if (!isAllFiller && builtGramSize == gramSize.Value)
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SlowSynonymMap.cs b/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SlowSynonymMap.cs
index 7a6f259..20a8169 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SlowSynonymMap.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SlowSynonymMap.cs
@@ -189,36 +189,38 @@ namespace Lucene.Net.Analysis.Synonym
             }
 
             int pos = 0;
-            var iter1 = lst1.GetEnumerator();
-            var iter2 = lst2.GetEnumerator();
-            var tok1 = iter1.MoveNext() ? iter1.Current : null;
-            var tok2 = iter2.MoveNext() ? iter2.Current : null;
-            int pos1 = tok1 != null ? tok1.PositionIncrement : 0;
-            int pos2 = tok2 != null ? tok2.PositionIncrement : 0;
-            while (tok1 != null || tok2 != null)
+            using (var iter1 = lst1.GetEnumerator())
+            using (var iter2 = lst2.GetEnumerator())
             {
-                while (tok1 != null && (pos1 <= pos2 || tok2 == null))
+                var tok1 = iter1.MoveNext() ? iter1.Current : null;
+                var tok2 = iter2.MoveNext() ? iter2.Current : null;
+                int pos1 = tok1 != null ? tok1.PositionIncrement : 0;
+                int pos2 = tok2 != null ? tok2.PositionIncrement : 0;
+                while (tok1 != null || tok2 != null)
                 {
-                    var tok = new Token(tok1.StartOffset, tok1.EndOffset, tok1.Type);
-                    tok.CopyBuffer(tok1.Buffer, 0, tok1.Length);
-                    tok.PositionIncrement = pos1 - pos;
-                    result.Add(tok);
-                    pos = pos1;
-                    tok1 = iter1.MoveNext() ? iter1.Current : null;
-                    pos1 += tok1 != null ? tok1.PositionIncrement : 0;
-                }
-                while (tok2 != null && (pos2 <= pos1 || tok1 == null))
-                {
-                    var tok = new Token(tok2.StartOffset, tok2.EndOffset, tok2.Type);
-                    tok.CopyBuffer(tok2.Buffer, 0, tok2.Length);
-                    tok.PositionIncrement = pos2 - pos;
-                    result.Add(tok);
-                    pos = pos2;
-                    tok2 = iter2.MoveNext() ? iter2.Current : null;
-                    pos2 += tok2 != null ? tok2.PositionIncrement : 0;
+                    while (tok1 != null && (pos1 <= pos2 || tok2 == null))
+                    {
+                        var tok = new Token(tok1.StartOffset, tok1.EndOffset, tok1.Type);
+                        tok.CopyBuffer(tok1.Buffer, 0, tok1.Length);
+                        tok.PositionIncrement = pos1 - pos;
+                        result.Add(tok);
+                        pos = pos1;
+                        tok1 = iter1.MoveNext() ? iter1.Current : null;
+                        pos1 += tok1 != null ? tok1.PositionIncrement : 0;
+                    }
+                    while (tok2 != null && (pos2 <= pos1 || tok1 == null))
+                    {
+                        var tok = new Token(tok2.StartOffset, tok2.EndOffset, tok2.Type);
+                        tok.CopyBuffer(tok2.Buffer, 0, tok2.Length);
+                        tok.PositionIncrement = pos2 - pos;
+                        result.Add(tok);
+                        pos = pos2;
+                        tok2 = iter2.MoveNext() ? iter2.Current : null;
+                        pos2 += tok2 != null ? tok2.PositionIncrement : 0;
+                    }
                 }
+                return result;
             }
-            return result;
         }
     }
 }
\ No newline at end of file
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
index cfe5625..480c4d6 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
@@ -214,10 +214,12 @@ namespace Lucene.Net.Analysis.Util
         /// <param name="arrayIndex">A 32-bit integer that represents the index in <paramref name="array"/> at which copying begins.</param>
         public virtual void CopyTo(KeyValuePair<string, TValue>[] array, int arrayIndex)
         {
-            var iter = (EntryIterator)EntrySet().GetEnumerator();
-            for (int i = arrayIndex; iter.MoveNext(); i++)
+            using (var iter = (EntryIterator)EntrySet().GetEnumerator())
             {
-                array[i] = new KeyValuePair<string, TValue>(iter.Current.Key, iter.CurrentValue);
+                for (int i = arrayIndex; iter.MoveNext(); i++)
+                {
+                    array[i] = new KeyValuePair<string, TValue>(iter.Current.Key, iter.CurrentValue);
+                }
             }
         }
 
@@ -228,10 +230,12 @@ namespace Lucene.Net.Analysis.Util
         /// <param name="map"></param>
         public virtual void CopyTo(CharArrayMap<TValue> map)
         {
-            var iter = (EntryIterator)EntrySet().GetEnumerator();
-            while(iter.MoveNext())
+            using (var iter = (EntryIterator)EntrySet().GetEnumerator())
             {
-                map.Put(iter.Current.Key, iter.CurrentValue);
+                while (iter.MoveNext())
+                {
+                    map.Put(iter.Current.Key, iter.CurrentValue);
+                }
             }
         }
 
@@ -758,14 +762,16 @@ namespace Lucene.Net.Analysis.Util
             if (this.Count != other.Count)
                 return false;
 
-            var iter = other.GetEnumerator();
-            while (iter.MoveNext())
+            using (var iter = other.GetEnumerator())
             {
-                if (!this.ContainsKey(iter.Current.Key))
-                    return false;
+                while (iter.MoveNext())
+                {
+                    if (!this.ContainsKey(iter.Current.Key))
+                        return false;
 
-                if (!EqualityComparer<TValue>.Default.Equals(this[iter.Current.Key], iter.Current.Value))
-                    return false;
+                    if (!EqualityComparer<TValue>.Default.Equals(this[iter.Current.Key], iter.Current.Value))
+                        return false;
+                }
             }
 
             return true;
@@ -1155,10 +1161,12 @@ namespace Lucene.Net.Analysis.Util
 
             public void CopyTo(string[] array, int arrayIndex)
             {
-                var iter = GetEnumerator();
-                for (int i = arrayIndex; iter.MoveNext(); i++)
+                using (var iter = GetEnumerator())
                 {
-                    array[i] = iter.Current;
+                    for (int i = arrayIndex; iter.MoveNext(); i++)
+                    {
+                        array[i] = iter.Current;
+                    }
                 }
             }
 
@@ -1289,23 +1297,25 @@ namespace Lucene.Net.Analysis.Util
 
             public override string ToString()
             {
-                var i = (ValueEnumerator)GetEnumerator();
-                if (!i.HasNext)
-                    return "[]";
-
-                StringBuilder sb = new StringBuilder();
-                sb.Append('[');
-                while(i.MoveNext())
+                using (var i = (ValueEnumerator)GetEnumerator())
                 {
-                    TValue value = i.Current;
-                    if (sb.Length > 1)
+                    if (!i.HasNext)
+                        return "[]";
+
+                    StringBuilder sb = new StringBuilder();
+                    sb.Append('[');
+                    while (i.MoveNext())
                     {
-                        sb.Append(',').Append(' ');
+                        TValue value = i.Current;
+                        if (sb.Length > 1)
+                        {
+                            sb.Append(',').Append(' ');
+                        }
+                        sb.Append(value.ToString());
                     }
-                    sb.Append(value.ToString());
-                }
 
-                return sb.Append(']').ToString();
+                    return sb.Append(']').ToString();
+                }
             }
 
             /// <summary>
@@ -1340,7 +1350,7 @@ namespace Lucene.Net.Analysis.Util
 
                 public void Dispose()
                 {
-                    // nothing to do
+                    entryIterator.Dispose();
                 }
 
                 public bool MoveNext()
@@ -1414,17 +1424,19 @@ namespace Lucene.Net.Analysis.Util
         {
             var sb = new StringBuilder("{");
 
-            IEnumerator<KeyValuePair<string, TValue>> iter1 = DictionaryExtensions.EntrySet(this).GetEnumerator();
-            while (iter1.MoveNext())
+            using (IEnumerator<KeyValuePair<string, TValue>> iter1 = DictionaryExtensions.EntrySet(this).GetEnumerator())
             {
-                KeyValuePair<string, TValue> entry = iter1.Current;
-                if (sb.Length > 1)
+                while (iter1.MoveNext())
                 {
-                    sb.Append(", ");
+                    KeyValuePair<string, TValue> entry = iter1.Current;
+                    if (sb.Length > 1)
+                    {
+                        sb.Append(", ");
+                    }
+                    sb.Append(entry.Key);
+                    sb.Append("=");
+                    sb.Append(entry.Value);
                 }
-                sb.Append(entry.Key);
-                sb.Append("=");
-                sb.Append(entry.Value);
             }
 
             return sb.Append('}').ToString();
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs
index 3b39cee..445ef59 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs
@@ -366,10 +366,12 @@ namespace Lucene.Net.Analysis.Util
         /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
         public void CopyTo(string[] array, int arrayIndex)
         {
-            var iter = map.OriginalKeySet.GetEnumerator();
-            for (int i = arrayIndex; iter.MoveNext(); i++)
+            using (var iter = map.OriginalKeySet.GetEnumerator())
             {
-                array[i] = iter.Current;
+                for (int i = arrayIndex; iter.MoveNext(); i++)
+                {
+                    array[i] = iter.Current;
+                }
             }
         }
 
diff --git a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Gener.cs b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Gener.cs
index bacfc68..b8defb9 100644
--- a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Gener.cs
+++ b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Gener.cs
@@ -106,9 +106,8 @@ namespace Egothor.Stemmer
         public bool Eat(Row @in, int[] remap)
         {
             int sum = 0;
-            for (IEnumerator<Cell> i = @in.cells.Values.GetEnumerator(); i.MoveNext();)
+            foreach (Cell c in @in.cells.Values)
             {
-                Cell c = i.Current;
                 sum += c.cnt;
                 if (c.@ref >= 0)
                 {
@@ -120,9 +119,8 @@ namespace Egothor.Stemmer
             }
             int frame = sum / 10;
             bool live = false;
-            for (IEnumerator<Cell> i = @in.cells.Values.GetEnumerator(); i.MoveNext();)
+            foreach (Cell c in @in.cells.Values)
             {
-                Cell c = i.Current;
                 if (c.cnt < frame && c.cmd >= 0)
                 {
                     c.cnt = 0;
diff --git a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Lift.cs b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Lift.cs
index 43a4602..d14a45c 100644
--- a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Lift.cs
+++ b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Lift.cs
@@ -116,10 +116,8 @@ namespace Egothor.Stemmer
         /// <param name="nodes">contains the patch commands</param>
         public void LiftUp(Row @in, IList<Row> nodes)
         {
-            IEnumerator<Cell> i = @in.cells.Values.GetEnumerator();
-            for (; i.MoveNext();)
+            foreach (Cell c in @in.cells.Values)
             {
-                Cell c = i.Current;
                 if (c.@ref >= 0)
                 {
                     Row to = nodes[c.@ref];
diff --git a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Optimizer.cs b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Optimizer.cs
index e299452..ed97f98 100644
--- a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Optimizer.cs
+++ b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Optimizer.cs
@@ -124,11 +124,9 @@ namespace Egothor.Stemmer
         /// <returns>the resulting <see cref="Row"/>, or <c>null</c> if the operation cannot be realized</returns>
         public Row Merge(Row master, Row existing)
         {
-            var i = master.cells.Keys.GetEnumerator();
             Row n = new Row();
-            for (; i.MoveNext();)
+            foreach (char ch in master.cells.Keys)
             {
-                char ch = i.Current;
                 // XXX also must handle Cnt and Skip !!
                 Cell a = master.cells.ContainsKey(ch) ? master.cells[ch] : null;
                 Cell b = existing.cells.ContainsKey(ch) ? existing.cells[ch] : null;
@@ -140,10 +138,8 @@ namespace Egothor.Stemmer
                 }
                 n.cells[ch] = s;
             }
-            i = existing.cells.Keys.GetEnumerator();
-            for (; i.MoveNext();)
+            foreach (char ch in existing.cells.Keys)
             {
-                char ch = i.Current;
                 if (master.At(ch) != null)
                 {
                     continue;
diff --git a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Reduce.cs b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Reduce.cs
index 61a1c3f..3b95735 100644
--- a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Reduce.cs
+++ b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Reduce.cs
@@ -93,10 +93,8 @@ namespace Egothor.Stemmer
 
             Row now = old[ind];
             to.Add(now);
-            IEnumerator<Cell> i = now.cells.Values.GetEnumerator();
-            for (; i.MoveNext();)
+            foreach (Cell c in now.cells.Values)
             {
-                Cell c = i.Current;
                 if (c.@ref >= 0 && remap[c.@ref] < 0)
                 {
                     RemoveGaps(c.@ref, old, to, remap);
@@ -111,19 +109,16 @@ namespace Egothor.Stemmer
         /// </summary>
         internal class Remap : Row
         {
-            /**
-             * Constructor for the <see cref="Remap"/> object
-             * 
-             * @param old Description of the Parameter
-             * @param remap Description of the Parameter
-             */
+            /// <summary>
+            /// Constructor for the <see cref="Remap"/> object
+            /// </summary>
+            /// <param name="old">Description of the Parameter</param>
+            /// <param name="remap">Description of the Parameter</param>
             public Remap(Row old, int[] remap)
-                        : base()
+                : base()
             {
-                var i = old.cells.Keys.GetEnumerator();
-                for (; i.MoveNext();)
+                foreach (char ch in old.cells.Keys)
                 {
-                    char ch = i.Current;
                     Cell c = old.At(ch);
                     Cell nc;
                     if (c.@ref >= 0)
diff --git a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Row.cs b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Row.cs
index 149b8e2..250972b 100644
--- a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Row.cs
+++ b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Row.cs
@@ -151,11 +151,9 @@ namespace Egothor.Stemmer
         /// <returns>the number of cells in use</returns>
         public int GetCells()
         {
-            IEnumerator<char> i = cells.Keys.GetEnumerator();
             int size = 0;
-            for (; i.MoveNext();)
+            foreach (char c in cells.Keys)
             {
-                char c = i.Current;
                 Cell e = At(c);
                 if (e.cmd >= 0 || e.@ref >= 0)
                 {
@@ -171,11 +169,9 @@ namespace Egothor.Stemmer
         /// <returns>the number of references</returns>
         public int GetCellsPnt()
         {
-            IEnumerator<char> i = cells.Keys.GetEnumerator();
             int size = 0;
-            for (; i.MoveNext();)
+            foreach (char c in cells.Keys)
             {
-                char c = i.Current;
                 Cell e = At(c);
                 if (e.@ref >= 0)
                 {
@@ -191,11 +187,9 @@ namespace Egothor.Stemmer
         /// <returns>the number of patch commands</returns>
         public int GetCellsVal()
         {
-            IEnumerator<char> i = cells.Keys.GetEnumerator();
             int size = 0;
-            for (; i.MoveNext();)
+            foreach (char c in cells.Keys)
             {
-                char c = i.Current;
                 Cell e = At(c);
                 if (e.cmd >= 0)
                 {
@@ -248,10 +242,8 @@ namespace Egothor.Stemmer
         public virtual void Store(IDataOutput os)
         {
             os.WriteInt32(cells.Count);
-            IEnumerator<char> i = cells.Keys.GetEnumerator();
-            for (; i.MoveNext();)
+            foreach (char c in cells.Keys)
             {
-                char c = i.Current;
                 Cell e = At(c);
                 if (e.cmd < 0 && e.@ref < 0)
                 {
@@ -274,13 +266,11 @@ namespace Egothor.Stemmer
         /// <returns>the number of identical <see cref="Cell"/>s, or -1 if there are (at least) two different <see cref="Cell"/>s</returns>
         public int UniformCmd(bool eqSkip)
         {
-            IEnumerator<Cell> i = cells.Values.GetEnumerator();
             int ret = -1;
             uniformCnt = 1;
             uniformSkip = 0;
-            for (; i.MoveNext();)
+            foreach (Cell c in cells.Values)
             {
-                Cell c = i.Current;
                 if (c.@ref >= 0)
                 {
                     return -1;
@@ -325,9 +315,8 @@ namespace Egothor.Stemmer
         /// <param name="out"></param>
         public virtual void Print(TextWriter @out)
         {
-            for (IEnumerator<char> i = cells.Keys.GetEnumerator(); i.MoveNext();)
+            foreach (char ch in cells.Keys)
             {
-                char ch = i.Current;
                 Cell c = At(ch);
                 @out.Write("[" + ch + ":" + c + "]");
             }
diff --git a/src/Lucene.Net.Benchmark/Support/Sax/Helpers/NamespaceSupport.cs b/src/Lucene.Net.Benchmark/Support/Sax/Helpers/NamespaceSupport.cs
index c4014a0..ac79d0a 100644
--- a/src/Lucene.Net.Benchmark/Support/Sax/Helpers/NamespaceSupport.cs
+++ b/src/Lucene.Net.Benchmark/Support/Sax/Helpers/NamespaceSupport.cs
@@ -424,6 +424,7 @@ namespace Sax.Helpers
         public IEnumerable GetPrefixes(string uri)
         {
             var prefixes = new ArrayList();
+            // LUCENENET NOTE: IEnumerator is not disposable
             IEnumerator allPrefixes = GetPrefixes().GetEnumerator();
             while (allPrefixes.MoveNext())
             {
diff --git a/src/Lucene.Net.Codecs/Memory/MemoryDocValuesConsumer.cs b/src/Lucene.Net.Codecs/Memory/MemoryDocValuesConsumer.cs
index 8bbb765..447d7f3 100644
--- a/src/Lucene.Net.Codecs/Memory/MemoryDocValuesConsumer.cs
+++ b/src/Lucene.Net.Codecs/Memory/MemoryDocValuesConsumer.cs
@@ -506,7 +506,8 @@ namespace Lucene.Net.Codecs.Memory
 
             public void Dispose()
             {
-                // nothing to do
+                this.counts.Dispose();
+                this.ords.Dispose();
             }
 
             public void Reset()
diff --git a/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs b/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs
index 3598d6a..fdb30ea 100644
--- a/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs
+++ b/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs
@@ -323,23 +323,25 @@ namespace Lucene.Net.Codecs.SimpleText
             // compute ord pattern: this is funny, we encode all values for all docs to find the maximum length
             var maxOrdListLength = 0;
             var sb2 = new StringBuilder();
-            var ordStream = ords.GetEnumerator();
-            foreach (var n in docToOrdCount)
+            using (var ordStream = ords.GetEnumerator())
             {
-                sb2.Length = 0;
-                var count = (int) n;
-                for (int i = 0; i < count; i++)
+                foreach (var n in docToOrdCount)
                 {
-                    ordStream.MoveNext();
-
-                    var ord = ordStream.Current;
-                    if (sb2.Length > 0)
+                    sb2.Length = 0;
+                    var count = (int)n;
+                    for (int i = 0; i < count; i++)
                     {
-                        sb2.Append(",");
+                        ordStream.MoveNext();
+
+                        var ord = ordStream.Current;
+                        if (sb2.Length > 0)
+                        {
+                            sb2.Append(",");
+                        }
+                        sb2.Append(ord.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
                     }
-                    sb2.Append(ord.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
+                    maxOrdListLength = Math.Max(maxOrdListLength, sb2.Length);
                 }
-                maxOrdListLength = Math.Max(maxOrdListLength, sb2.Length);
             }
 
             sb2.Length = 0;
@@ -379,30 +381,31 @@ namespace Lucene.Net.Codecs.SimpleText
 
             Debug.Assert(valuesSeen == valueCount);
 
-            ordStream = ords.GetEnumerator();
-
-            // write the ords for each doc comma-separated
-            foreach (var n in docToOrdCount)
+            using (var ordStream = ords.GetEnumerator())
             {
-                sb2.Length = 0;
-                var count = (int) n;
-                for (var i = 0; i < count; i++)
+                // write the ords for each doc comma-separated
+                foreach (var n in docToOrdCount)
                 {
-                    ordStream.MoveNext();
-                    var ord = ordStream.Current;
-                    if (sb2.Length > 0)
-                        sb2.Append(",");
-                    
-                    sb2.Append(ord);
-                }
-                // now pad to fit: these are numbers so spaces work well. reader calls trim()
-                var numPadding = maxOrdListLength - sb2.Length;
-                for (var i = 0; i < numPadding; i++)
-                {
-                    sb2.Append(' ');
+                    sb2.Length = 0;
+                    var count = (int)n;
+                    for (var i = 0; i < count; i++)
+                    {
+                        ordStream.MoveNext();
+                        var ord = ordStream.Current;
+                        if (sb2.Length > 0)
+                            sb2.Append(",");
+
+                        sb2.Append(ord);
+                    }
+                    // now pad to fit: these are numbers so spaces work well. reader calls trim()
+                    var numPadding = maxOrdListLength - sb2.Length;
+                    for (var i = 0; i < numPadding; i++)
+                    {
+                        sb2.Append(' ');
+                    }
+                    SimpleTextUtil.Write(data, sb2.ToString(), scratch);
+                    SimpleTextUtil.WriteNewline(data);
                 }
-                SimpleTextUtil.Write(data, sb2.ToString(), scratch);
-                SimpleTextUtil.WriteNewline(data);
             }
         }
 
diff --git a/src/Lucene.Net.Facet/Taxonomy/WriterCache/CompactLabelToOrdinal.cs b/src/Lucene.Net.Facet/Taxonomy/WriterCache/CompactLabelToOrdinal.cs
index dd68485..b71f3aa 100644
--- a/src/Lucene.Net.Facet/Taxonomy/WriterCache/CompactLabelToOrdinal.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/WriterCache/CompactLabelToOrdinal.cs
@@ -212,12 +212,13 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
             this.collisionMap = new CollisionMap(oldCollisionMap.Capacity, this.labelRepository);
             this.threshold = (int)(this.capacity * this.loadFactor);
 
-            var it = oldCollisionMap.GetEnumerator();
-
-            while (it.MoveNext())
+            using (var it = oldCollisionMap.GetEnumerator())
             {
-                var e = it.Current;
-                AddLabelOffset(StringHashCode(this.labelRepository, e.offset), e.cid, e.offset);
+                while (it.MoveNext())
+                {
+                    var e = it.Current;
+                    AddLabelOffset(StringHashCode(this.labelRepository, e.offset), e.cid, e.offset);
+                }
             }
         }
 
diff --git a/src/Lucene.Net.Highlighter/VectorHighlight/BaseFragListBuilder.cs b/src/Lucene.Net.Highlighter/VectorHighlight/BaseFragListBuilder.cs
index 96f1900..842956e 100644
--- a/src/Lucene.Net.Highlighter/VectorHighlight/BaseFragListBuilder.cs
+++ b/src/Lucene.Net.Highlighter/VectorHighlight/BaseFragListBuilder.cs
@@ -58,59 +58,61 @@ namespace Lucene.Net.Search.VectorHighlight
                 throw new ArgumentException("fragCharSize(" + fragCharSize + ") is too small. It must be " + minFragCharSize + " or higher.");
 
             List<WeightedPhraseInfo> wpil = new List<WeightedPhraseInfo>();
-            IteratorQueue<WeightedPhraseInfo> queue = new IteratorQueue<WeightedPhraseInfo>(fieldPhraseList.PhraseList.GetEnumerator());
-            WeightedPhraseInfo phraseInfo = null;
-            int startOffset = 0;
-            while ((phraseInfo = queue.Top()) != null)
+            using (IteratorQueue<WeightedPhraseInfo> queue = new IteratorQueue<WeightedPhraseInfo>(fieldPhraseList.PhraseList.GetEnumerator()))
             {
-                // if the phrase violates the border of previous fragment, discard it and try next phrase
-                if (phraseInfo.StartOffset < startOffset)
+                WeightedPhraseInfo phraseInfo = null;
+                int startOffset = 0;
+                while ((phraseInfo = queue.Top()) != null)
                 {
-                    queue.RemoveTop();
-                    continue;
-                }
+                    // if the phrase violates the border of previous fragment, discard it and try next phrase
+                    if (phraseInfo.StartOffset < startOffset)
+                    {
+                        queue.RemoveTop();
+                        continue;
+                    }
 
-                wpil.Clear();
-                int currentPhraseStartOffset = phraseInfo.StartOffset;
-                int currentPhraseEndOffset = phraseInfo.EndOffset;
-                int spanStart = Math.Max(currentPhraseStartOffset - margin, startOffset);
-                int spanEnd = Math.Max(currentPhraseEndOffset, spanStart + fragCharSize);
-                if (AcceptPhrase(queue.RemoveTop(), currentPhraseEndOffset - currentPhraseStartOffset, fragCharSize))
-                {
-                    wpil.Add(phraseInfo);
-                }
-                while ((phraseInfo = queue.Top()) != null)
-                { // pull until we crossed the current spanEnd
-                    if (phraseInfo.EndOffset <= spanEnd)
+                    wpil.Clear();
+                    int currentPhraseStartOffset = phraseInfo.StartOffset;
+                    int currentPhraseEndOffset = phraseInfo.EndOffset;
+                    int spanStart = Math.Max(currentPhraseStartOffset - margin, startOffset);
+                    int spanEnd = Math.Max(currentPhraseEndOffset, spanStart + fragCharSize);
+                    if (AcceptPhrase(queue.RemoveTop(), currentPhraseEndOffset - currentPhraseStartOffset, fragCharSize))
                     {
-                        currentPhraseEndOffset = phraseInfo.EndOffset;
-                        if (AcceptPhrase(queue.RemoveTop(), currentPhraseEndOffset - currentPhraseStartOffset, fragCharSize))
+                        wpil.Add(phraseInfo);
+                    }
+                    while ((phraseInfo = queue.Top()) != null)
+                    { // pull until we crossed the current spanEnd
+                        if (phraseInfo.EndOffset <= spanEnd)
+                        {
+                            currentPhraseEndOffset = phraseInfo.EndOffset;
+                            if (AcceptPhrase(queue.RemoveTop(), currentPhraseEndOffset - currentPhraseStartOffset, fragCharSize))
+                            {
+                                wpil.Add(phraseInfo);
+                            }
+                        }
+                        else
                         {
-                            wpil.Add(phraseInfo);
+                            break;
                         }
                     }
-                    else
+                    if (!wpil.Any())
                     {
-                        break;
+                        continue;
                     }
-                }
-                if (!wpil.Any())
-                {
-                    continue;
-                }
 
-                int matchLen = currentPhraseEndOffset - currentPhraseStartOffset;
-                // now recalculate the start and end position to "center" the result
-                int newMargin = Math.Max(0, (fragCharSize - matchLen) / 2); // matchLen can be > fragCharSize prevent IAOOB here
-                spanStart = currentPhraseStartOffset - newMargin;
-                if (spanStart < startOffset)
-                {
-                    spanStart = startOffset;
+                    int matchLen = currentPhraseEndOffset - currentPhraseStartOffset;
+                    // now recalculate the start and end position to "center" the result
+                    int newMargin = Math.Max(0, (fragCharSize - matchLen) / 2); // matchLen can be > fragCharSize prevent IAOOB here
+                    spanStart = currentPhraseStartOffset - newMargin;
+                    if (spanStart < startOffset)
+                    {
+                        spanStart = startOffset;
+                    }
+                    // whatever is bigger here we grow this out
+                    spanEnd = spanStart + Math.Max(matchLen, fragCharSize);
+                    startOffset = spanEnd;
+                    fieldFragList.Add(spanStart, spanEnd, wpil);
                 }
-                // whatever is bigger here we grow this out
-                spanEnd = spanStart + Math.Max(matchLen, fragCharSize);
-                startOffset = spanEnd;
-                fieldFragList.Add(spanStart, spanEnd, wpil);
             }
             return fieldFragList;
         }
@@ -131,7 +133,7 @@ namespace Lucene.Net.Search.VectorHighlight
             return info.TermsOffsets.Count <= 1 || matchLength <= fragCharSize;
         }
 
-        private sealed class IteratorQueue<T>
+        private sealed class IteratorQueue<T> : IDisposable // LUCENENET specific - implemented IDisposable to dispose the IEnumerator<T>
         {
             private readonly IEnumerator<T> iter;
             private T top;
@@ -161,6 +163,11 @@ namespace Lucene.Net.Search.VectorHighlight
                 }
                 return currentTop;
             }
+
+            public void Dispose()
+            {
+                iter.Dispose();
+            }
         }
     }
 }
diff --git a/src/Lucene.Net.Highlighter/VectorHighlight/BaseFragmentsBuilder.cs b/src/Lucene.Net.Highlighter/VectorHighlight/BaseFragmentsBuilder.cs
index 6f77027..29adb50 100644
--- a/src/Lucene.Net.Highlighter/VectorHighlight/BaseFragmentsBuilder.cs
+++ b/src/Lucene.Net.Highlighter/VectorHighlight/BaseFragmentsBuilder.cs
@@ -293,39 +293,43 @@ namespace Lucene.Net.Search.VectorHighlight
                     List<SubInfo> fragInfo_SubInfos_ToDelete = new List<SubInfo>();
 
                     List<SubInfo> subInfos = new List<SubInfo>();
-                    IEnumerator<SubInfo> subInfoIterator = fragInfo.SubInfos.GetEnumerator();
                     float boost = 0.0f;  //  The boost of the new info will be the sum of the boosts of its SubInfos
-                    while (subInfoIterator.MoveNext())
+                    using (IEnumerator<SubInfo> subInfoIterator = fragInfo.SubInfos.GetEnumerator())
                     {
-                        SubInfo subInfo = subInfoIterator.Current;
-                        List<Toffs> toffsList = new List<Toffs>();
+                        while (subInfoIterator.MoveNext())
+                        {
+                            SubInfo subInfo = subInfoIterator.Current;
+                            List<Toffs> toffsList = new List<Toffs>();
 
 
-                        IEnumerator<Toffs> toffsIterator = subInfo.TermsOffsets.GetEnumerator();
-                        while (toffsIterator.MoveNext())
-                        {
-                            Toffs toffs = toffsIterator.Current;
-                            if (toffs.StartOffset >= fieldStart && toffs.EndOffset <= fieldEnd)
+                            using (IEnumerator<Toffs> toffsIterator = subInfo.TermsOffsets.GetEnumerator())
                             {
-
-                                toffsList.Add(toffs);
-                                //toffsIterator.Remove();
+                                while (toffsIterator.MoveNext())
+                                {
+                                    Toffs toffs = toffsIterator.Current;
+                                    if (toffs.StartOffset >= fieldStart && toffs.EndOffset <= fieldEnd)
+                                    {
+
+                                        toffsList.Add(toffs);
+                                        //toffsIterator.Remove();
+                                    }
+                                }
                             }
-                        }
-                        if (toffsList.Any())
-                        {
-                            // LUCENENET NOTE: Instead of removing during iteration (which isn't allowed in .NET when using an IEnumerator), 
-                            // we just remove the items at this point. We only get here if there are items to remove.
-                            subInfo.TermsOffsets.RemoveAll(toffsList);
+                            if (toffsList.Any())
+                            {
+                                // LUCENENET NOTE: Instead of removing during iteration (which isn't allowed in .NET when using an IEnumerator), 
+                                // we just remove the items at this point. We only get here if there are items to remove.
+                                subInfo.TermsOffsets.RemoveAll(toffsList);
 
-                            subInfos.Add(new SubInfo(subInfo.Text, toffsList, subInfo.Seqnum, subInfo.Boost));
-                            boost += subInfo.Boost;
-                        }
+                                subInfos.Add(new SubInfo(subInfo.Text, toffsList, subInfo.Seqnum, subInfo.Boost));
+                                boost += subInfo.Boost;
+                            }
 
-                        if (!subInfo.TermsOffsets.Any())
-                        {
-                            //subInfoIterator.Remove();
-                            fragInfo_SubInfos_ToDelete.Add(subInfo);
+                            if (!subInfo.TermsOffsets.Any())
+                            {
+                                //subInfoIterator.Remove();
+                                fragInfo_SubInfos_ToDelete.Add(subInfo);
+                            }
                         }
                     }
 
diff --git a/src/Lucene.Net.Highlighter/VectorHighlight/FastVectorHighlighter.cs b/src/Lucene.Net.Highlighter/VectorHighlight/FastVectorHighlighter.cs
index 4a37bd8..a78b3ac 100644
--- a/src/Lucene.Net.Highlighter/VectorHighlight/FastVectorHighlighter.cs
+++ b/src/Lucene.Net.Highlighter/VectorHighlight/FastVectorHighlighter.cs
@@ -250,7 +250,6 @@ namespace Lucene.Net.Search.VectorHighlight
             FieldQuery fieldQuery, IndexReader reader, int docId,
             ISet<string> matchedFields, int fragCharSize)
         {
-            IEnumerator<string> matchedFieldsItr = matchedFields.GetEnumerator();
             if (!matchedFields.Any())
             {
                 throw new ArgumentException("matchedFields must contain at least on field name.");
@@ -258,9 +257,9 @@ namespace Lucene.Net.Search.VectorHighlight
             FieldPhraseList[]
             toMerge = new FieldPhraseList[matchedFields.Count];
             int i = 0;
-            while (matchedFieldsItr.MoveNext())
+            foreach (var matchedField in matchedFields)
             {
-                FieldTermStack stack = new FieldTermStack(reader, docId, matchedFieldsItr.Current, fieldQuery);
+                FieldTermStack stack = new FieldTermStack(reader, docId, matchedField, fieldQuery);
                 toMerge[i++] = new FieldPhraseList(stack, fieldQuery, phraseLimit);
             }
             return fragListBuilder.CreateFieldFragList(new FieldPhraseList(toMerge), fragCharSize);
diff --git a/src/Lucene.Net.Highlighter/VectorHighlight/FieldPhraseList.cs b/src/Lucene.Net.Highlighter/VectorHighlight/FieldPhraseList.cs
index 136cb82..93a2e3a 100644
--- a/src/Lucene.Net.Highlighter/VectorHighlight/FieldPhraseList.cs
+++ b/src/Lucene.Net.Highlighter/VectorHighlight/FieldPhraseList.cs
@@ -149,54 +149,66 @@ namespace Lucene.Net.Search.VectorHighlight
             // Step 1.  Sort by startOffset, endOffset, and boost, in that order.
 
             IEnumerator<WeightedPhraseInfo>[] allInfos = new IEnumerator<WeightedPhraseInfo>[toMerge.Length];
-            int index = 0;
-            foreach (FieldPhraseList fplToMerge in toMerge)
+            try
             {
-                allInfos[index++] = fplToMerge.phraseList.GetEnumerator();
-            }
-            MergedIterator<WeightedPhraseInfo> itr = new MergedIterator<WeightedPhraseInfo>(false, allInfos);
-            // Step 2.  Walk the sorted list merging infos that overlap
-            phraseList = new List<WeightedPhraseInfo>();
-            if (!itr.MoveNext())
-            {
-                return;
-            }
-            List<WeightedPhraseInfo> work = new List<WeightedPhraseInfo>();
-            WeightedPhraseInfo first = itr.Current;
-            work.Add(first);
-            int workEndOffset = first.EndOffset;
-            while (itr.MoveNext())
-            {
-                WeightedPhraseInfo current = itr.Current;
-                if (current.StartOffset <= workEndOffset)
+                int index = 0;
+                foreach (FieldPhraseList fplToMerge in toMerge)
                 {
-                    workEndOffset = Math.Max(workEndOffset, current.EndOffset);
-                    work.Add(current);
+                    allInfos[index++] = fplToMerge.phraseList.GetEnumerator();
                 }
-                else
+                using (MergedIterator<WeightedPhraseInfo> itr = new MergedIterator<WeightedPhraseInfo>(false, allInfos))
                 {
+                    // Step 2.  Walk the sorted list merging infos that overlap
+                    phraseList = new List<WeightedPhraseInfo>();
+                    if (!itr.MoveNext())
+                    {
+                        return;
+                    }
+                    List<WeightedPhraseInfo> work = new List<WeightedPhraseInfo>();
+                    WeightedPhraseInfo first = itr.Current;
+                    work.Add(first);
+                    int workEndOffset = first.EndOffset;
+                    while (itr.MoveNext())
+                    {
+                        WeightedPhraseInfo current = itr.Current;
+                        if (current.StartOffset <= workEndOffset)
+                        {
+                            workEndOffset = Math.Max(workEndOffset, current.EndOffset);
+                            work.Add(current);
+                        }
+                        else
+                        {
+                            if (work.Count == 1)
+                            {
+                                phraseList.Add(work[0]);
+                                work[0] = current;
+                            }
+                            else
+                            {
+                                phraseList.Add(new WeightedPhraseInfo(work));
+                                work.Clear();
+                                work.Add(current);
+                            }
+                            workEndOffset = current.EndOffset;
+                        }
+                    }
                     if (work.Count == 1)
                     {
                         phraseList.Add(work[0]);
-                        work[0] = current;
                     }
                     else
                     {
                         phraseList.Add(new WeightedPhraseInfo(work));
                         work.Clear();
-                        work.Add(current);
                     }
-                    workEndOffset = current.EndOffset;
                 }
             }
-            if (work.Count == 1)
-            {
-                phraseList.Add(work[0]);
-            }
-            else
+            finally
             {
-                phraseList.Add(new WeightedPhraseInfo(work));
-                work.Clear();
+                foreach (var allInfo in allInfos)
+                {
+                    allInfo.Dispose();
+                }
             }
         }
 
@@ -307,50 +319,67 @@ namespace Lucene.Net.Search.VectorHighlight
             /// </summary>
             public WeightedPhraseInfo(ICollection<WeightedPhraseInfo> toMerge)
             {
-                // Pretty much the same idea as merging FieldPhraseLists:
-                // Step 1.  Sort by startOffset, endOffset
-                //          While we are here merge the boosts and termInfos
-                IEnumerator<WeightedPhraseInfo> toMergeItr = toMerge.GetEnumerator();
-                if (!toMergeItr.MoveNext())
-                {
-                    throw new ArgumentException("toMerge must contain at least one WeightedPhraseInfo.");
-                }
-                WeightedPhraseInfo first = toMergeItr.Current;
                 IEnumerator<Toffs>[] allToffs = new IEnumerator<Toffs>[toMerge.Count];
-                termsInfos = new List<TermInfo>();
-                seqnum = first.seqnum;
-                boost = first.boost;
-                allToffs[0] = first.termsOffsets.GetEnumerator();
-                int index = 1;
-                while (toMergeItr.MoveNext())
+                try
                 {
-                    WeightedPhraseInfo info = toMergeItr.Current;
-                    boost += info.boost;
-                    termsInfos.AddAll(info.termsInfos);
-                    allToffs[index++] = info.termsOffsets.GetEnumerator();
-                }
-                // Step 2.  Walk the sorted list merging overlaps
-                MergedIterator<Toffs> itr = new MergedIterator<Toffs>(false, allToffs);
-                termsOffsets = new List<Toffs>();
-                if (!itr.MoveNext())
-                {
-                    return;
-                }
-                Toffs work = itr.Current;
-                while (itr.MoveNext())
-                {
-                    Toffs current = itr.Current;
-                    if (current.StartOffset <= work.EndOffset)
+
+                    // Pretty much the same idea as merging FieldPhraseLists:
+                    // Step 1.  Sort by startOffset, endOffset
+                    //          While we are here merge the boosts and termInfos
+                    using (IEnumerator<WeightedPhraseInfo> toMergeItr = toMerge.GetEnumerator())
                     {
-                        work.EndOffset = Math.Max(work.EndOffset, current.EndOffset);
+                        if (!toMergeItr.MoveNext())
+                        {
+                            throw new ArgumentException("toMerge must contain at least one WeightedPhraseInfo.");
+                        }
+                        WeightedPhraseInfo first = toMergeItr.Current;
+
+                        termsInfos = new List<TermInfo>();
+                        seqnum = first.seqnum;
+                        boost = first.boost;
+                        allToffs[0] = first.termsOffsets.GetEnumerator();
+                        int index = 1;
+                        while (toMergeItr.MoveNext())
+                        {
+                            WeightedPhraseInfo info = toMergeItr.Current;
+                            boost += info.boost;
+                            termsInfos.AddAll(info.termsInfos);
+                            allToffs[index++] = info.termsOffsets.GetEnumerator();
+                        }
+
+                        // Step 2.  Walk the sorted list merging overlaps
+                        using (MergedIterator<Toffs> itr = new MergedIterator<Toffs>(false, allToffs))
+                        {
+                            termsOffsets = new List<Toffs>();
+                            if (!itr.MoveNext())
+                            {
+                                return;
+                            }
+                            Toffs work = itr.Current;
+                            while (itr.MoveNext())
+                            {
+                                Toffs current = itr.Current;
+                                if (current.StartOffset <= work.EndOffset)
+                                {
+                                    work.EndOffset = Math.Max(work.EndOffset, current.EndOffset);
+                                }
+                                else
+                                {
+                                    termsOffsets.Add(work);
+                                    work = current;
+                                }
+                            }
+                            termsOffsets.Add(work);
+                        }
                     }
-                    else
+                }
+                finally
+                {
+                    foreach (var allToff in allToffs)
                     {
-                        termsOffsets.Add(work);
-                        work = current;
+                        allToff.Dispose();
                     }
                 }
-                termsOffsets.Add(work);
             }
 
             public virtual int StartOffset
diff --git a/src/Lucene.Net.Highlighter/VectorHighlight/SingleFragListBuilder.cs b/src/Lucene.Net.Highlighter/VectorHighlight/SingleFragListBuilder.cs
index 37a3947..cd843d6 100644
--- a/src/Lucene.Net.Highlighter/VectorHighlight/SingleFragListBuilder.cs
+++ b/src/Lucene.Net.Highlighter/VectorHighlight/SingleFragListBuilder.cs
@@ -38,19 +38,21 @@ namespace Lucene.Net.Search.VectorHighlight
             FieldFragList ffl = new SimpleFieldFragList(fragCharSize);
 
             List<WeightedPhraseInfo> wpil = new List<WeightedPhraseInfo>();
-            IEnumerator<WeightedPhraseInfo> ite = fieldPhraseList.PhraseList.GetEnumerator();
-            WeightedPhraseInfo phraseInfo = null;
-            while (true)
+            using (IEnumerator<WeightedPhraseInfo> ite = fieldPhraseList.PhraseList.GetEnumerator())
             {
-                if (!ite.MoveNext()) break;
-                phraseInfo = ite.Current;
-                if (phraseInfo == null) break;
+                WeightedPhraseInfo phraseInfo = null;
+                while (true)
+                {
+                    if (!ite.MoveNext()) break;
+                    phraseInfo = ite.Current;
+                    if (phraseInfo == null) break;
 
-                wpil.Add(phraseInfo);
+                    wpil.Add(phraseInfo);
+                }
+                if (wpil.Count > 0)
+                    ffl.Add(0, int.MaxValue, wpil);
+                return ffl;
             }
-            if (wpil.Count > 0)
-                ffl.Add(0, int.MaxValue, wpil);
-            return ffl;
         }
     }
 }
diff --git a/src/Lucene.Net.Memory/MemoryIndex.cs b/src/Lucene.Net.Memory/MemoryIndex.cs
index d278ab9..2b951f8 100644
--- a/src/Lucene.Net.Memory/MemoryIndex.cs
+++ b/src/Lucene.Net.Memory/MemoryIndex.cs
@@ -629,10 +629,12 @@ namespace Lucene.Net.Index.Memory
             int size = map.Count;
             KeyValuePair<K, V>[] entries = new KeyValuePair<K, V>[size];
 
-            IEnumerator<KeyValuePair<K, V>> iter = map.GetEnumerator();
-            for (int i = 0; i < size && iter.MoveNext(); i++)
+            using (IEnumerator<KeyValuePair<K, V>> iter = map.GetEnumerator())
             {
-                entries[i] = iter.Current;
+                for (int i = 0; i < size && iter.MoveNext(); i++)
+                {
+                    entries[i] = iter.Current;
+                }
             }
 
             if (size > 1)
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
index 0a9b9e0..e310e62 100644
--- a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
@@ -67,9 +67,9 @@ namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
 
             StringBuilder sb = new StringBuilder();
             string filler = "";
-            for (IEnumerator<IQueryNode> it = children.GetEnumerator(); it.MoveNext();)
+            foreach (var child in children)
             {
-                sb.Append(filler).Append(it.Current.ToQueryString(escapeSyntaxParser));
+                sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
                 filler = " OR ";
             }
 
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
index 0a54974..87a8b19 100644
--- a/src/Lucene.Net.QueryParser/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
@@ -60,10 +60,10 @@ namespace Lucene.Net.QueryParsers.Flexible.Core.Processors
                 {
                     removeBoolean = true;
 
-                    for (IEnumerator<IQueryNode> it = children.GetEnumerator(); it.MoveNext();)
+                    foreach (var child in children)
                     {
 
-                        if (!(it.Current is DeletedQueryNode))
+                        if (!(child is DeletedQueryNode))
                         {
                             removeBoolean = false;
                             break;
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Parser/StandardSyntaxParser.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Parser/StandardSyntaxParser.cs
index 0cc249d..f69e99d 100644
--- a/src/Lucene.Net.QueryParser/Flexible/Standard/Parser/StandardSyntaxParser.cs
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Parser/StandardSyntaxParser.cs
@@ -1180,25 +1180,28 @@ namespace Lucene.Net.QueryParsers.Flexible.Standard.Parser
                 {
                     jj_expentry[i] = jj_lasttokens[i];
                 }
-                 for (var it = jj_expentries.GetEnumerator(); it.MoveNext();)
+                using (var it = jj_expentries.GetEnumerator())
                 {
-                    int[] oldentry = (int[])(it.Current);
-                    if (oldentry.Length == jj_expentry.Length)
+                    while (it.MoveNext())
                     {
-                        for (int i = 0; i < jj_expentry.Length; i++)
+                        int[] oldentry = (int[])(it.Current);
+                        if (oldentry.Length == jj_expentry.Length)
                         {
-                            if (oldentry[i] != jj_expentry[i])
+                            for (int i = 0; i < jj_expentry.Length; i++)
                             {
-                                goto jj_entries_loop_continue;
+                                if (oldentry[i] != jj_expentry[i])
+                                {
+                                    goto jj_entries_loop_continue;
+                                }
                             }
+                            jj_expentries.Add(jj_expentry);
+                            goto jj_entries_loop_break;
                         }
-                        jj_expentries.Add(jj_expentry);
-                        goto jj_entries_loop_break;
+                        jj_entries_loop_continue: { }
                     }
-                    jj_entries_loop_continue: { }
+                    jj_entries_loop_break:
+                        if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
                 }
-                jj_entries_loop_break:
-                if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
             }
         }
 
diff --git a/src/Lucene.Net.Sandbox/Queries/FuzzyLikeThisQuery.cs b/src/Lucene.Net.Sandbox/Queries/FuzzyLikeThisQuery.cs
index 3cc7e2c..9ed11b4 100644
--- a/src/Lucene.Net.Sandbox/Queries/FuzzyLikeThisQuery.cs
+++ b/src/Lucene.Net.Sandbox/Queries/FuzzyLikeThisQuery.cs
@@ -305,9 +305,8 @@ namespace Lucene.Net.Sandbox.Queries
                 l.Add(st);
             }
             //Step 2: Organize the sorted termqueries into zero-coord scoring boolean queries
-            for (var iter = variantQueries.Values.GetEnumerator(); iter.MoveNext();)
+            foreach (List<ScoreTerm> variants in variantQueries.Values)
             {
-                List<ScoreTerm> variants = iter.Current;
                 if (variants.Count == 1)
                 {
                     //optimize where only one selected variant
@@ -319,10 +318,8 @@ namespace Lucene.Net.Sandbox.Queries
                 else
                 {
                     BooleanQuery termVariants = new BooleanQuery(true); //disable coord and IDF for these term variants
-                    for (IEnumerator<ScoreTerm> iterator2 = variants.GetEnumerator(); iterator2
-                            .MoveNext();)
+                    foreach (ScoreTerm st in variants)
                     {
-                        ScoreTerm st = iterator2.Current;
                         // found a match
                         Query tq = ignoreTF ? (Query)new ConstantScoreQuery(new TermQuery(st.Term)) : new TermQuery(st.Term, 1);
                         tq.Boost = st.Score; // set the boost using the ScoreTerm's score
diff --git a/src/Lucene.Net.TestFramework/Codecs/Asserting/AssertingDocValuesFormat.cs b/src/Lucene.Net.TestFramework/Codecs/Asserting/AssertingDocValuesFormat.cs
index 564efd2..37419f7 100644
--- a/src/Lucene.Net.TestFramework/Codecs/Asserting/AssertingDocValuesFormat.cs
+++ b/src/Lucene.Net.TestFramework/Codecs/Asserting/AssertingDocValuesFormat.cs
@@ -159,36 +159,38 @@ namespace Lucene.Net.Codecs.Asserting
                 int docCount = 0;
                 long ordCount = 0;
                 Int64BitSet seenOrds = new Int64BitSet(valueCount);
-                IEnumerator<long?> ordIterator = ords.GetEnumerator();
-                foreach (long? v in docToOrdCount)
+                using (IEnumerator<long?> ordIterator = ords.GetEnumerator())
                 {
-                    Debug.Assert(v != null);
-                    int count = (int)v.Value;
-                    Debug.Assert(count >= 0);
-                    docCount++;
-                    ordCount += count;
-
-                    long lastOrd = -1;
-                    for (int i = 0; i < count; i++)
+                    foreach (long? v in docToOrdCount)
                     {
-                        ordIterator.MoveNext();
-                        long? o = ordIterator.Current;
-                        Debug.Assert(o != null);
-                        long ord = o.Value;
-                        Debug.Assert(ord >= 0 && ord < valueCount);
-                        Debug.Assert(ord > lastOrd, "ord=" + ord + ",lastOrd=" + lastOrd);
-                        seenOrds.Set(ord);
-                        lastOrd = ord;
+                        Debug.Assert(v != null);
+                        int count = (int)v.Value;
+                        Debug.Assert(count >= 0);
+                        docCount++;
+                        ordCount += count;
+
+                        long lastOrd = -1;
+                        for (int i = 0; i < count; i++)
+                        {
+                            ordIterator.MoveNext();
+                            long? o = ordIterator.Current;
+                            Debug.Assert(o != null);
+                            long ord = o.Value;
+                            Debug.Assert(ord >= 0 && ord < valueCount);
+                            Debug.Assert(ord > lastOrd, "ord=" + ord + ",lastOrd=" + lastOrd);
+                            seenOrds.Set(ord);
+                            lastOrd = ord;
+                        }
                     }
+                    Debug.Assert(ordIterator.MoveNext() == false);
+
+                    Debug.Assert(docCount == MaxDoc);
+                    Debug.Assert(seenOrds.Cardinality() == valueCount);
+                    CheckIterator(values.GetEnumerator(), valueCount, false);
+                    CheckIterator(docToOrdCount.GetEnumerator(), MaxDoc, false);
+                    CheckIterator(ords.GetEnumerator(), ordCount, false);
+                    @in.AddSortedSetField(field, values, docToOrdCount, ords);
                 }
-                Debug.Assert(ordIterator.MoveNext() == false);
-
-                Debug.Assert(docCount == MaxDoc);
-                Debug.Assert(seenOrds.Cardinality() == valueCount);
-                CheckIterator(values.GetEnumerator(), valueCount, false);
-                CheckIterator(docToOrdCount.GetEnumerator(), MaxDoc, false);
-                CheckIterator(ords.GetEnumerator(), ordCount, false);
-                @in.AddSortedSetField(field, values, docToOrdCount, ords);
             }
 
             protected override void Dispose(bool disposing)
@@ -246,32 +248,39 @@ namespace Lucene.Net.Codecs.Asserting
 
         private static void CheckIterator<T>(IEnumerator<T> iterator, long expectedSize, bool allowNull)
         {
-            for (long i = 0; i < expectedSize; i++)
+            try
             {
-                bool hasNext = iterator.MoveNext();
-                Debug.Assert(hasNext);
-                T v = iterator.Current;
-                Debug.Assert(allowNull || v != null);
-                try
+                for (long i = 0; i < expectedSize; i++)
                 {
-                    iterator.Reset();
-                    throw new InvalidOperationException("broken iterator (supports remove): " + iterator);
+                    bool hasNext = iterator.MoveNext();
+                    Debug.Assert(hasNext);
+                    T v = iterator.Current;
+                    Debug.Assert(allowNull || v != null);
+                    try
+                    {
+                        iterator.Reset();
+                        throw new InvalidOperationException("broken iterator (supports remove): " + iterator);
+                    }
+                    catch (System.NotSupportedException)
+                    {
+                        // ok
+                    }
                 }
-                catch (System.NotSupportedException)
+                Debug.Assert(!iterator.MoveNext());
+                /*try
                 {
-                    // ok
+                  //iterator.next();
+                  throw new InvalidOperationException("broken iterator (allows next() when hasNext==false) " + iterator);
                 }
+                catch (Exception)
+                {
+                  // ok
+                }*/
             }
-            Debug.Assert(!iterator.MoveNext());
-            /*try
+            finally
             {
-              //iterator.next();
-              throw new InvalidOperationException("broken iterator (allows next() when hasNext==false) " + iterator);
+                iterator.Dispose();
             }
-            catch (Exception)
-            {
-              // ok
-            }*/
         }
 
         internal class AssertingDocValuesProducer : DocValuesProducer
diff --git a/src/Lucene.Net.TestFramework/Codecs/MissingOrdRemapper.cs b/src/Lucene.Net.TestFramework/Codecs/MissingOrdRemapper.cs
index 87c3afe..3b0c253 100644
--- a/src/Lucene.Net.TestFramework/Codecs/MissingOrdRemapper.cs
+++ b/src/Lucene.Net.TestFramework/Codecs/MissingOrdRemapper.cs
@@ -56,17 +56,17 @@ namespace Lucene.Net.Codecs
 
             private class IteratorAnonymousInnerClassHelper : IEnumerator<BytesRef>
             {
-                private readonly IterableAnonymousInnerClassHelper OuterInstance;
+                private readonly IterableAnonymousInnerClassHelper outerInstance;
 
                 public IteratorAnonymousInnerClassHelper(IterableAnonymousInnerClassHelper outerInstance)
                 {
-                    this.OuterInstance = outerInstance;
+                    this.outerInstance = outerInstance;
                     seenEmpty = false;
                     @in = outerInstance.Iterable.GetEnumerator();
                 }
 
                 private bool seenEmpty;
-                private IEnumerator<BytesRef> @in;
+                private readonly IEnumerator<BytesRef> @in;
                 private BytesRef current;
 
                 public bool MoveNext()
@@ -104,6 +104,7 @@ namespace Lucene.Net.Codecs
 
                 public void Dispose()
                 {
+                    @in.Dispose();
                 }
             }
         }
@@ -136,15 +137,15 @@ namespace Lucene.Net.Codecs
 
             private class IteratorAnonymousInnerClassHelper2 : IEnumerator<long?>
             {
-                private readonly IterableAnonymousInnerClassHelper2 OuterInstance;
+                private readonly IterableAnonymousInnerClassHelper2 outerInstance;
 
                 public IteratorAnonymousInnerClassHelper2(IterableAnonymousInnerClassHelper2 outerInstance)
                 {
-                    this.OuterInstance = outerInstance;
+                    this.outerInstance = outerInstance;
                     @in = outerInstance.Iterable.GetEnumerator();
                 }
 
-                private IEnumerator<long?> @in;
+                private readonly IEnumerator<long?> @in;
                 private long current;
 
                 public bool MoveNext()
@@ -178,6 +179,7 @@ namespace Lucene.Net.Codecs
 
                 public void Dispose()
                 {
+                    @in.Dispose();
                 }
             }
         }
@@ -210,15 +212,15 @@ namespace Lucene.Net.Codecs
 
             private class IteratorAnonymousInnerClassHelper3 : IEnumerator<long?>
             {
-                private readonly IterableAnonymousInnerClassHelper3 OuterInstance;
+                private readonly IterableAnonymousInnerClassHelper3 outerInstance;
 
                 public IteratorAnonymousInnerClassHelper3(IterableAnonymousInnerClassHelper3 outerInstance)
                 {
-                    this.OuterInstance = outerInstance;
+                    this.outerInstance = outerInstance;
                     @in = outerInstance.Iterable.GetEnumerator();
                 }
 
-                private IEnumerator<long?> @in;
+                private readonly IEnumerator<long?> @in;
                 private long current;
 
                 public bool MoveNext()
@@ -251,6 +253,7 @@ namespace Lucene.Net.Codecs
 
                 public void Dispose()
                 {
+                    @in.Dispose();
                 }
             }
         }
diff --git a/src/Lucene.Net.TestFramework/Index/FieldFilterAtomicReader.cs b/src/Lucene.Net.TestFramework/Index/FieldFilterAtomicReader.cs
index e3e66dc..5fa7296 100644
--- a/src/Lucene.Net.TestFramework/Index/FieldFilterAtomicReader.cs
+++ b/src/Lucene.Net.TestFramework/Index/FieldFilterAtomicReader.cs
@@ -74,7 +74,8 @@ namespace Lucene.Net.Index
             f = new FieldFilterFields(this, f);
             // we need to check for emptyness, so we can return
             // null:
-            return f.GetEnumerator().MoveNext() ? f : null;
+            using (var iter = f.GetEnumerator())
+                return iter.MoveNext() ? f : null;
         }
 
         public override void Document(int docID, StoredFieldVisitor visitor)
diff --git a/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs b/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs
index 0cf1daf..af700cc 100644
--- a/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs
+++ b/src/Lucene.Net.TestFramework/JavaCompatibility/SystemTypesHelpers.cs
@@ -251,18 +251,18 @@ namespace Lucene.Net
 
             if (s.Count > list.Count())
             {
-                for (var i = list.GetEnumerator(); i.MoveNext();)
-                    modified |= s.Remove(i.Current);
+                foreach (var item in list)
+                    modified |= s.Remove(item);
             }
             else
             {
                 List<T> toRemove = new List<T>();
 
-                for (var i = s.GetEnumerator(); i.MoveNext();)
+                foreach (var item in s)
                 {
-                    if (list.Contains(i.Current))
+                    if (list.Contains(item))
                     {
-                        toRemove.Add(i.Current);
+                        toRemove.Add(item);
                     }
                 }
 
diff --git a/src/Lucene.Net.TestFramework/Store/MockDirectoryWrapper.cs b/src/Lucene.Net.TestFramework/Store/MockDirectoryWrapper.cs
index c8063a6..25af9f3 100644
--- a/src/Lucene.Net.TestFramework/Store/MockDirectoryWrapper.cs
+++ b/src/Lucene.Net.TestFramework/Store/MockDirectoryWrapper.cs
@@ -292,108 +292,110 @@ namespace Lucene.Net.Store
                 OpenFiles = new Dictionary<string, int>();
                 OpenFilesForWrite = new HashSet<string>();
                 OpenFilesDeleted = new HashSet<string>();
-                IEnumerator<string> it = UnSyncedFiles.GetEnumerator();
-                UnSyncedFiles = new HashSet<string>();
-                // first force-close all files, so we can corrupt on windows etc.
-                // clone the file map, as these guys want to remove themselves on close.
-                var m = new IdentityHashMap<IDisposable, Exception>(OpenFileHandles);
-                foreach (IDisposable f in m.Keys)
+                using (IEnumerator<string> it = UnSyncedFiles.GetEnumerator())
                 {
-                    try
+                    UnSyncedFiles = new HashSet<string>();
+                    // first force-close all files, so we can corrupt on windows etc.
+                    // clone the file map, as these guys want to remove themselves on close.
+                    var m = new IdentityHashMap<IDisposable, Exception>(OpenFileHandles);
+                    foreach (IDisposable f in m.Keys)
                     {
-                        f.Dispose();
-                    }
+                        try
+                        {
+                            f.Dispose();
+                        }
 #pragma warning disable 168
-                    catch (Exception ignored)
+                        catch (Exception ignored)
 #pragma warning restore 168
-                    {
-                        //Debug.WriteLine("Crash(): f.Dispose() FAILED for {0}:\n{1}", f.ToString(), ignored.ToString());
-                    }
-                }
-
-                while (it.MoveNext())
-                {
-                    string name = it.Current;
-                    int damage = RandomState.Next(5);
-                    string action = null;
-
-                    if (damage == 0)
-                    {
-                        action = "deleted";
-                        DeleteFile(name, true);
-                    }
-                    else if (damage == 1)
-                    {
-                        action = "zeroed";
-                        // Zero out file entirely
-                        long length = FileLength(name);
-                        var zeroes = new byte[256];
-                        long upto = 0;
-                        using (IndexOutput @out = m_input.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState)))
                         {
-                            while (upto < length)
-                            {
-                                var limit = (int)Math.Min(length - upto, zeroes.Length);
-                                @out.WriteBytes(zeroes, 0, limit);
-                                upto += limit;
-                            }
+                            //Debug.WriteLine("Crash(): f.Dispose() FAILED for {0}:\n{1}", f.ToString(), ignored.ToString());
                         }
                     }
-                    else if (damage == 2)
+
+                    while (it.MoveNext())
                     {
-                        action = "partially truncated";
-                        // Partially Truncate the file:
+                        string name = it.Current;
+                        int damage = RandomState.Next(5);
+                        string action = null;
 
-                        // First, make temp file and copy only half this
-                        // file over:
-                        string tempFileName;
-                        while (true)
+                        if (damage == 0)
+                        {
+                            action = "deleted";
+                            DeleteFile(name, true);
+                        }
+                        else if (damage == 1)
                         {
-                            tempFileName = "" + RandomState.Next();
-                            if (!LuceneTestCase.SlowFileExists(m_input, tempFileName))
+                            action = "zeroed";
+                            // Zero out file entirely
+                            long length = FileLength(name);
+                            var zeroes = new byte[256];
+                            long upto = 0;
+                            using (IndexOutput @out = m_input.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState)))
                             {
-                                break;
+                                while (upto < length)
+                                {
+                                    var limit = (int)Math.Min(length - upto, zeroes.Length);
+                                    @out.WriteBytes(zeroes, 0, limit);
+                                    upto += limit;
+                                }
                             }
                         }
-                        using (IndexOutput tempOut = m_input.CreateOutput(tempFileName, LuceneTestCase.NewIOContext(RandomState)))
+                        else if (damage == 2)
                         {
-                            using (IndexInput ii = m_input.OpenInput(name, LuceneTestCase.NewIOContext(RandomState)))
+                            action = "partially truncated";
+                            // Partially Truncate the file:
+
+                            // First, make temp file and copy only half this
+                            // file over:
+                            string tempFileName;
+                            while (true)
                             {
-                                tempOut.CopyBytes(ii, ii.Length / 2);
+                                tempFileName = "" + RandomState.Next();
+                                if (!LuceneTestCase.SlowFileExists(m_input, tempFileName))
+                                {
+                                    break;
+                                }
+                            }
+                            using (IndexOutput tempOut = m_input.CreateOutput(tempFileName, LuceneTestCase.NewIOContext(RandomState)))
+                            {
+                                using (IndexInput ii = m_input.OpenInput(name, LuceneTestCase.NewIOContext(RandomState)))
+                                {
+                                    tempOut.CopyBytes(ii, ii.Length / 2);
+                                }
                             }
-                        }
 
-                        // Delete original and copy bytes back:
-                        DeleteFile(name, true);
+                            // Delete original and copy bytes back:
+                            DeleteFile(name, true);
 
-                        using (IndexOutput @out = m_input.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState)))
+                            using (IndexOutput @out = m_input.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState)))
+                            {
+                                using (IndexInput ii = m_input.OpenInput(tempFileName, LuceneTestCase.NewIOContext(RandomState)))
+                                {
+                                    @out.CopyBytes(ii, ii.Length);
+                                }
+                            }
+                            DeleteFile(tempFileName, true);
+                        }
+                        else if (damage == 3)
                         {
-                            using (IndexInput ii = m_input.OpenInput(tempFileName, LuceneTestCase.NewIOContext(RandomState)))
+                            // The file survived intact:
+                            action = "didn't change";
+                        }
+                        else
+                        {
+                            action = "fully truncated";
+                            // Totally truncate the file to zero bytes
+                            DeleteFile(name, true);
+                            using (IndexOutput @out = m_input.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState)))
                             {
-                                @out.CopyBytes(ii, ii.Length);
+                                @out.Length = 0;
                             }
                         }
-                        DeleteFile(tempFileName, true);
-                    }
-                    else if (damage == 3)
-                    {
-                        // The file survived intact:
-                        action = "didn't change";
-                    }
-                    else
-                    {
-                        action = "fully truncated";
-                        // Totally truncate the file to zero bytes
-                        DeleteFile(name, true);
-                        using (IndexOutput @out = m_input.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState)))
+                        if (LuceneTestCase.VERBOSE)
                         {
-                            @out.Length = 0;
+                            Console.WriteLine("MockDirectoryWrapper: " + action + " unsynced file: " + name);
                         }
                     }
-                    if (LuceneTestCase.VERBOSE)
-                    {
-                        Console.WriteLine("MockDirectoryWrapper: " + action + " unsynced file: " + name);
-                    }
                 }
             }
         }
@@ -928,12 +930,7 @@ namespace Lucene.Net.Store
                     if (OpenFiles.Count > 0)
                     {
                         // print the first one as its very verbose otherwise
-                        Exception cause = null;
-                        IEnumerator<Exception> stacktraces = OpenFileHandles.Values.GetEnumerator();
-                        if (stacktraces.MoveNext())
-                        {
-                            cause = stacktraces.Current;
-                        }
+                        Exception cause = OpenFileHandles.Values.FirstOrDefault();
 
                         // RuntimeException instead ofSystem.IO.IOException because
                         // super() does not throwSystem.IO.IOException currently:
diff --git a/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs b/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
index 45eb5a4..eff930c 100644
--- a/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
@@ -1946,17 +1946,18 @@ namespace Lucene.Net.Util
             }
             AssertFieldStatisticsEquals(info, leftFields, rightFields);
 
-            IEnumerator<string> leftEnum = leftFields.GetEnumerator();
-            IEnumerator<string> rightEnum = rightFields.GetEnumerator();
-
-            while (leftEnum.MoveNext())
+            using (IEnumerator<string> leftEnum = leftFields.GetEnumerator())
+            using (IEnumerator<string> rightEnum = rightFields.GetEnumerator())
             {
-                string field = leftEnum.Current;
-                rightEnum.MoveNext();
-                Assert.AreEqual(field, rightEnum.Current, info);
-                AssertTermsEquals(info, leftReader, leftFields.GetTerms(field), rightFields.GetTerms(field), deep);
+                while (leftEnum.MoveNext())
+                {
+                    string field = leftEnum.Current;
+                    rightEnum.MoveNext();
+                    Assert.AreEqual(field, rightEnum.Current, info);
+                    AssertTermsEquals(info, leftReader, leftFields.GetTerms(field), rightFields.GetTerms(field), deep);
+                }
+                Assert.IsFalse(rightEnum.MoveNext());
             }
-            Assert.IsFalse(rightEnum.MoveNext());
         }
 
         /// <summary>
@@ -2410,14 +2411,16 @@ namespace Lucene.Net.Util
                 leftDoc.Fields.Sort(comp);
                 rightDoc.Fields.Sort(comp);
 
-                var leftIterator = leftDoc.GetEnumerator();
-                var rightIterator = rightDoc.GetEnumerator();
-                while (leftIterator.MoveNext())
+                using (var leftIterator = leftDoc.GetEnumerator())
+                using (var rightIterator = rightDoc.GetEnumerator())
                 {
-                    Assert.IsTrue(rightIterator.MoveNext(), info);
-                    AssertStoredFieldEquals(info, leftIterator.Current, rightIterator.Current);
+                    while (leftIterator.MoveNext())
+                    {
+                        Assert.IsTrue(rightIterator.MoveNext(), info);
+                        AssertStoredFieldEquals(info, leftIterator.Current, rightIterator.Current);
+                    }
+                    Assert.IsFalse(rightIterator.MoveNext(), info);
                 }
-                Assert.IsFalse(rightIterator.MoveNext(), info);
             }
         }
 
diff --git a/src/Lucene.Net/Index/CoalescedUpdates.cs b/src/Lucene.Net/Index/CoalescedUpdates.cs
index 5ce47a9..7b0e21b 100644
--- a/src/Lucene.Net/Index/CoalescedUpdates.cs
+++ b/src/Lucene.Net/Index/CoalescedUpdates.cs
@@ -134,6 +134,7 @@ namespace Lucene.Net.Index
 
                 public void Dispose()
                 {
+                    iter.Dispose();
                 }
 
                 public bool MoveNext()
diff --git a/src/Lucene.Net/Index/IndexWriter.cs b/src/Lucene.Net/Index/IndexWriter.cs
index 4984d97..7009d45 100644
--- a/src/Lucene.Net/Index/IndexWriter.cs
+++ b/src/Lucene.Net/Index/IndexWriter.cs
@@ -558,7 +558,6 @@ namespace Lucene.Net.Index
                 lock (this)
                 {
                     Exception priorE = null;
-                    IEnumerator<KeyValuePair<SegmentCommitInfo, ReadersAndUpdates>> it = readerMap.GetEnumerator();
 
                     // LUCENENET specific - Since an enumerator doesn't allow you to delete 
                     // immediately, keep track of which elements we have iterated over so
@@ -566,9 +565,9 @@ namespace Lucene.Net.Index
                     // end of the block.
                     IList<KeyValuePair<SegmentCommitInfo, ReadersAndUpdates>> toDelete = new List<KeyValuePair<SegmentCommitInfo, ReadersAndUpdates>>();
 
-                    while (it.MoveNext())
+                    foreach (var pair in readerMap)
                     {
-                        ReadersAndUpdates rld = it.Current.Value;
+                        ReadersAndUpdates rld = pair.Value;
 
                         try
                         {
@@ -612,7 +611,7 @@ namespace Lucene.Net.Index
                         // so we store the elements that are iterated over and
                         // delete as soon as we are done iterating (whether
                         // that is because of an exception or not).
-                        toDelete.Add(it.Current);
+                        toDelete.Add(pair);
 
                         // NOTE: it is allowed that these decRefs do not
                         // actually close the SRs; this happens when a
diff --git a/src/Lucene.Net/Search/BooleanQuery.cs b/src/Lucene.Net/Search/BooleanQuery.cs
index 80ae085..8f7404c 100644
--- a/src/Lucene.Net/Search/BooleanQuery.cs
+++ b/src/Lucene.Net/Search/BooleanQuery.cs
@@ -341,49 +341,50 @@ namespace Lucene.Net.Search
                 float sum = 0.0f;
                 bool fail = false;
                 int shouldMatchCount = 0;
-                IEnumerator<BooleanClause> cIter = outerInstance.clauses.GetEnumerator();
-                for (IEnumerator<Weight> wIter = m_weights.GetEnumerator(); wIter.MoveNext(); )
+                using (IEnumerator<BooleanClause> cIter = outerInstance.clauses.GetEnumerator())
                 {
-                    Weight w = wIter.Current;
-                    cIter.MoveNext();
-                    BooleanClause c = cIter.Current;
-                    if (w.GetScorer(context, context.AtomicReader.LiveDocs) == null)
+                    foreach (Weight w in m_weights)
                     {
-                        if (c.IsRequired)
+                        cIter.MoveNext();
+                        BooleanClause c = cIter.Current;
+                        if (w.GetScorer(context, context.AtomicReader.LiveDocs) == null)
                         {
-                            fail = true;
-                            Explanation r = new Explanation(0.0f, "no match on required clause (" + c.Query.ToString() + ")");
-                            sumExpl.AddDetail(r);
+                            if (c.IsRequired)
+                            {
+                                fail = true;
+                                Explanation r = new Explanation(0.0f, "no match on required clause (" + c.Query.ToString() + ")");
+                                sumExpl.AddDetail(r);
+                            }
+                            continue;
                         }
-                        continue;
-                    }
-                    Explanation e = w.Explain(context, doc);
-                    if (e.IsMatch)
-                    {
-                        if (!c.IsProhibited)
+                        Explanation e = w.Explain(context, doc);
+                        if (e.IsMatch)
                         {
-                            sumExpl.AddDetail(e);
-                            sum += e.Value;
-                            coord++;
+                            if (!c.IsProhibited)
+                            {
+                                sumExpl.AddDetail(e);
+                                sum += e.Value;
+                                coord++;
+                            }
+                            else
+                            {
+                                Explanation r = new Explanation(0.0f, "match on prohibited clause (" + c.Query.ToString() + ")");
+                                r.AddDetail(e);
+                                sumExpl.AddDetail(r);
+                                fail = true;
+                            }
+                            if (c.Occur == Occur_e.SHOULD)
+                            {
+                                shouldMatchCount++;
+                            }
                         }
-                        else
+                        else if (c.IsRequired)
                         {
-                            Explanation r = new Explanation(0.0f, "match on prohibited clause (" + c.Query.ToString() + ")");
+                            Explanation r = new Explanation(0.0f, "no match on required clause (" + c.Query.ToString() + ")");
                             r.AddDetail(e);
                             sumExpl.AddDetail(r);
                             fail = true;
                         }
-                        if (c.Occur == Occur_e.SHOULD)
-                        {
-                            shouldMatchCount++;
-                        }
-                    }
-                    else if (c.IsRequired)
-                    {
-                        Explanation r = new Explanation(0.0f, "no match on required clause (" + c.Query.ToString() + ")");
-                        r.AddDetail(e);
-                        sumExpl.AddDetail(r);
-                        fail = true;
                     }
                 }
                 if (fail)
@@ -429,33 +430,35 @@ namespace Lucene.Net.Search
 
                 IList<BulkScorer> prohibited = new List<BulkScorer>();
                 IList<BulkScorer> optional = new List<BulkScorer>();
-                IEnumerator<BooleanClause> cIter = outerInstance.clauses.GetEnumerator();
-                foreach (Weight w in m_weights)
-                {
-                    cIter.MoveNext();
-                    BooleanClause c = cIter.Current;
-                    BulkScorer subScorer = w.GetBulkScorer(context, false, acceptDocs);
-                    if (subScorer == null)
+                using (IEnumerator<BooleanClause> cIter = outerInstance.clauses.GetEnumerator())
+                { 
+                    foreach (Weight w in m_weights)
                     {
-                        if (c.IsRequired)
+                        cIter.MoveNext();
+                        BooleanClause c = cIter.Current;
+                        BulkScorer subScorer = w.GetBulkScorer(context, false, acceptDocs);
+                        if (subScorer == null)
                         {
-                            return null;
+                            if (c.IsRequired)
+                            {
+                                return null;
+                            }
+                        }
+                        else if (c.IsRequired)
+                        {
+                            // TODO: there are some cases where BooleanScorer
+                            // would handle conjunctions faster than
+                            // BooleanScorer2...
+                            return base.GetBulkScorer(context, scoreDocsInOrder, acceptDocs);
+                        }
+                        else if (c.IsProhibited)
+                        {
+                            prohibited.Add(subScorer);
+                        }
+                        else
+                        {
+                            optional.Add(subScorer);
                         }
-                    }
-                    else if (c.IsRequired)
-                    {
-                        // TODO: there are some cases where BooleanScorer
-                        // would handle conjunctions faster than
-                        // BooleanScorer2...
-                        return base.GetBulkScorer(context, scoreDocsInOrder, acceptDocs);
-                    }
-                    else if (c.IsProhibited)
-                    {
-                        prohibited.Add(subScorer);
-                    }
-                    else
-                    {
-                        optional.Add(subScorer);
                     }
                 }
 
diff --git a/src/Lucene.Net/Search/MultiPhraseQuery.cs b/src/Lucene.Net/Search/MultiPhraseQuery.cs
index 0a68b64..5e36a95 100644
--- a/src/Lucene.Net/Search/MultiPhraseQuery.cs
+++ b/src/Lucene.Net/Search/MultiPhraseQuery.cs
@@ -396,12 +396,10 @@ namespace Lucene.Net.Search
 
             buffer.Append("\"");
             int k = 0;
-            IEnumerator<Term[]> i = termArrays.GetEnumerator();
             int? lastPos = -1;
             bool first = true;
-            while (i.MoveNext())
+            foreach (Term[] terms in termArrays)
             {
-                Term[] terms = i.Current;
                 int? position = positions[k];
                 if (first)
                 {
@@ -546,10 +544,8 @@ namespace Lucene.Net.Search
             internal DocsQueue(ICollection<DocsAndPositionsEnum> docsEnums)
                 : base(docsEnums.Count)
             {
-                IEnumerator<DocsAndPositionsEnum> i = docsEnums.GetEnumerator();
-                while (i.MoveNext())
+                foreach (DocsAndPositionsEnum postings in docsEnums)
                 {
-                    DocsAndPositionsEnum postings = i.Current;
                     if (postings.NextDoc() != DocIdSetIterator.NO_MORE_DOCS)
                     {
                         Add(postings);
diff --git a/src/Lucene.Net/Search/Payloads/PayloadNearQuery.cs b/src/Lucene.Net/Search/Payloads/PayloadNearQuery.cs
index 60fcba0..f4dc779 100644
--- a/src/Lucene.Net/Search/Payloads/PayloadNearQuery.cs
+++ b/src/Lucene.Net/Search/Payloads/PayloadNearQuery.cs
@@ -87,11 +87,9 @@ namespace Lucene.Net.Search.Payloads
         {
             StringBuilder buffer = new StringBuilder();
             buffer.Append("payloadNear([");
-            IEnumerator<SpanQuery> i = m_clauses.GetEnumerator();
             bool hasCommaSpace = false;
-            while (i.MoveNext())
+            foreach (SpanQuery clause in m_clauses)
             {
-                SpanQuery clause = i.Current;
                 buffer.Append(clause.ToString(field));
                 buffer.Append(", ");
                 hasCommaSpace = true;
diff --git a/src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs b/src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs
index db74e74..57281e9 100644
--- a/src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs
+++ b/src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs
@@ -114,10 +114,9 @@ namespace Lucene.Net.Search.Payloads
             }
             else if (query is DisjunctionMaxQuery)
             {
-                IEnumerator<Query> enumerator = ((DisjunctionMaxQuery)query).GetEnumerator();
-                while (enumerator.MoveNext())
+                foreach (var q in ((DisjunctionMaxQuery)query))
                 {
-                    QueryToSpanQuery(enumerator.Current, payloads);
+                    QueryToSpanQuery(q, payloads);
                 }
             }
             else if (query is MultiPhraseQuery)
diff --git a/src/Lucene.Net/Search/Spans/SpanNearQuery.cs b/src/Lucene.Net/Search/Spans/SpanNearQuery.cs
index 9b6449e..5ea2a87 100644
--- a/src/Lucene.Net/Search/Spans/SpanNearQuery.cs
+++ b/src/Lucene.Net/Search/Spans/SpanNearQuery.cs
@@ -129,11 +129,9 @@ namespace Lucene.Net.Search.Spans
         {
             StringBuilder buffer = new StringBuilder();
             buffer.Append("SpanNear([");
-            IEnumerator<SpanQuery> i = m_clauses.GetEnumerator();
             bool isFirst = true;
-            while (i.MoveNext())
+            foreach (SpanQuery clause in m_clauses)
             {
-                SpanQuery clause = i.Current;
                 if (!isFirst)
                 {
                     buffer.Append(", ");
diff --git a/src/Lucene.Net/Search/Spans/SpanOrQuery.cs b/src/Lucene.Net/Search/Spans/SpanOrQuery.cs
index 0893ca9..f55f8aa 100644
--- a/src/Lucene.Net/Search/Spans/SpanOrQuery.cs
+++ b/src/Lucene.Net/Search/Spans/SpanOrQuery.cs
@@ -134,11 +134,9 @@ namespace Lucene.Net.Search.Spans
         {
             StringBuilder buffer = new StringBuilder();
             buffer.Append("spanOr([");
-            IEnumerator<SpanQuery> i = clauses.GetEnumerator();
             bool first = true;
-            while (i.MoveNext())
+            foreach (SpanQuery clause in clauses)
             {
-                SpanQuery clause = i.Current;
                 if (!first) buffer.Append(", ");
                 buffer.Append(clause.ToString(field));
                 first = false;
@@ -241,10 +239,9 @@ namespace Lucene.Net.Search.Spans
             private bool InitSpanQueue(int target)
             {
                 queue = new SpanQueue(outerInstance, outerInstance.clauses.Count);
-                IEnumerator<SpanQuery> i = outerInstance.clauses.GetEnumerator();
-                while (i.MoveNext())
+                foreach (var clause in outerInstance.clauses)
                 {
-                    Spans spans = i.Current.GetSpans(context, acceptDocs, termContexts);
+                    Spans spans = clause.GetSpans(context, acceptDocs, termContexts);
                     cost += spans.GetCost();
                     if (((target == -1) && spans.Next()) || ((target != -1) && spans.SkipTo(target)))
                     {
diff --git a/src/Lucene.Net/Search/Spans/SpanPayloadCheckQuery.cs b/src/Lucene.Net/Search/Spans/SpanPayloadCheckQuery.cs
index c9928ad..53b1487 100644
--- a/src/Lucene.Net/Search/Spans/SpanPayloadCheckQuery.cs
+++ b/src/Lucene.Net/Search/Spans/SpanPayloadCheckQuery.cs
@@ -62,16 +62,18 @@ namespace Lucene.Net.Search.Spans
                 if (candidate.Count == m_payloadToMatch.Count)
                 {
                     //TODO: check the byte arrays are the same
-                    var toMatchIter = m_payloadToMatch.GetEnumerator();
-                    //check each of the byte arrays, in order
-                    //hmm, can't rely on order here
-                    foreach (var candBytes in candidate)
+                    using (var toMatchIter = m_payloadToMatch.GetEnumerator())
                     {
-                        toMatchIter.MoveNext();
-                        //if one is a mismatch, then return false
-                        if (Arrays.Equals(candBytes, toMatchIter.Current) == false)
+                        //check each of the byte arrays, in order
+                        //hmm, can't rely on order here
+                        foreach (var candBytes in candidate)
                         {
-                            return AcceptStatus.NO;
+                            toMatchIter.MoveNext();
+                            //if one is a mismatch, then return false
+                            if (Arrays.Equals(candBytes, toMatchIter.Current) == false)
+                            {
+                                return AcceptStatus.NO;
+                            }
                         }
                     }
                     //we've verified all the bytes
diff --git a/src/Lucene.Net/Support/HashMap.cs b/src/Lucene.Net/Support/HashMap.cs
index db8723e..f01b6ee 100644
--- a/src/Lucene.Net/Support/HashMap.cs
+++ b/src/Lucene.Net/Support/HashMap.cs
@@ -166,21 +166,23 @@ namespace Lucene.Net.Support
 
             try
             {
-                var i = GetEnumerator();
-                while (i.MoveNext())
+                using (var i = GetEnumerator())
                 {
-                    KeyValuePair<TKey, TValue> e = i.Current;
-                    TKey key = e.Key;
-                    TValue value = e.Value;
-                    if (value == null)
+                    while (i.MoveNext())
                     {
-                        if (!(m[key] == null && m.ContainsKey(key)))
-                            return false;
-                    }
-                    else
-                    {
-                        if (!value.Equals(m[key]))
-                            return false;
+                        KeyValuePair<TKey, TValue> e = i.Current;
+                        TKey key = e.Key;
+                        TValue value = e.Value;
+                        if (value == null)
+                        {
+                            if (!(m[key] == null && m.ContainsKey(key)))
+                                return false;
+                        }
+                        else
+                        {
+                            if (!value.Equals(m[key]))
+                                return false;
+                        }
                     }
                 }
             }
@@ -199,31 +201,35 @@ namespace Lucene.Net.Support
         public override int GetHashCode()
         {
             int h = 0;
-            var i = GetEnumerator();
-            while (i.MoveNext())
-                h += i.Current.GetHashCode();
+            using (var i = GetEnumerator())
+            {
+                while (i.MoveNext())
+                    h += i.Current.GetHashCode();
+            }
             return h;
         }
 
         public override string ToString()
         {
-            var i = GetEnumerator();
-            if (!i.MoveNext())
-                return "{}";
-
-            StringBuilder sb = new StringBuilder();
-            sb.Append('{');
-            for (;;)
-            {
-                var e = i.Current;
-                TKey key = e.Key;
-                TValue value = e.Value;
-                sb.Append(key);
-                sb.Append('=');
-                sb.Append(value);
+            using (var i = GetEnumerator())
+            {
                 if (!i.MoveNext())
-                    return sb.Append('}').ToString();
-                sb.Append(',').Append(' ');
+                    return "{}";
+
+                StringBuilder sb = new StringBuilder();
+                sb.Append('{');
+                for (; ; )
+                {
+                    var e = i.Current;
+                    TKey key = e.Key;
+                    TValue value = e.Value;
+                    sb.Append(key);
+                    sb.Append('=');
+                    sb.Append(value);
+                    if (!i.MoveNext())
+                        return sb.Append('}').ToString();
+                    sb.Append(',').Append(' ');
+                }
             }
         }
 
diff --git a/src/Lucene.Net/Support/TreeSet.cs b/src/Lucene.Net/Support/TreeSet.cs
index f0d78c7..c1532f3 100644
--- a/src/Lucene.Net/Support/TreeSet.cs
+++ b/src/Lucene.Net/Support/TreeSet.cs
@@ -1150,65 +1150,68 @@ namespace Lucene.Net.Support
 
         void addSorted(SCG.IEnumerable<T> items, bool safe, bool raise)
         {
-            SCG.IEnumerator<T> e = items.GetEnumerator(); ;
-            if (size > 0)
-                throw new InternalException("This can't happen");
-
-            if (!e.MoveNext())
-                return;
+            using (SCG.IEnumerator<T> e = items.GetEnumerator())
+            {
+                if (size > 0)
+                    throw new InternalException("This can't happen");
 
-            //To count theCollect 
-            Node head = new Node(), tail = head;
-            int z = 1;
-            T lastitem = tail.item = e.Current;
+                if (!e.MoveNext())
+                    return;
 
+                //To count theCollect 
+                Node head = new Node(), tail = head;
+                int z = 1;
+                T lastitem = tail.item = e.Current;
 
-            while (e.MoveNext())
-            {
 
-                z++;
-                tail.right = new Node();
-                tail = tail.right;
-                tail.item = e.Current;
-                if (safe)
+                while (e.MoveNext())
                 {
-                    if (comparer.Compare(lastitem, tail.item) >= 0)
-                        throw new ArgumentException("Argument not sorted");
 
-                    lastitem = tail.item;
+                    z++;
+                    tail.right = new Node();
+                    tail = tail.right;
+                    tail.item = e.Current;
+                    if (safe)
+                    {
+                        if (comparer.Compare(lastitem, tail.item) >= 0)
+                            throw new ArgumentException("Argument not sorted");
+
+                        lastitem = tail.item;
+                    }
+                    tail.generation = generation;
+
                 }
-                tail.generation = generation;
 
-            }
 
-            int blackheight = 0, red = z, maxred = 1;
+                int blackheight = 0, red = z, maxred = 1;
 
-            while (maxred <= red)
-            {
-                red -= maxred;
-                maxred <<= 1;
-                blackheight++;
-            }
+                while (maxred <= red)
+                {
+                    red -= maxred;
+                    maxred <<= 1;
+                    blackheight++;
+                }
 
-            root = TreeSet<T>.maketreer(ref head, blackheight, maxred, red);
-            blackdepth = blackheight;
-            size = z;
+                root = TreeSet<T>.maketreer(ref head, blackheight, maxred, red);
+                blackdepth = blackheight;
+                size = z;
 
 
-            if (raise)
-            {
-                if ((ActiveEvents & EventTypeEnum.Added) != 0)
+                if (raise)
                 {
-                    CircularQueue<T> wasAdded = new CircularQueue<T>();
-                    foreach (T item in this)
-                        wasAdded.Enqueue(item);
-                    foreach (T item in wasAdded)
-                        raiseItemsAdded(item, 1);
+                    if ((ActiveEvents & EventTypeEnum.Added) != 0)
+                    {
+                        CircularQueue<T> wasAdded = new CircularQueue<T>();
+                        foreach (T item in this)
+                            wasAdded.Enqueue(item);
+                        foreach (T item in wasAdded)
+                            raiseItemsAdded(item, 1);
+                    }
+                    if ((ActiveEvents & EventTypeEnum.Changed) != 0)
+                        raiseCollectionChanged();
                 }
-                if ((ActiveEvents & EventTypeEnum.Changed) != 0)
-                    raiseCollectionChanged();
+                return;
             }
-            return;
         }
 
         #endregion
@@ -1909,23 +1912,25 @@ namespace Lucene.Net.Support
             if ((ActiveEvents & EventTypeEnum.Removed) != 0)
             {
                 wasRemoved = new CircularQueue<KeyValuePair<T, int>>();
-                SCG.IEnumerator<KeyValuePair<T, int>> ie = ItemMultiplicities().GetEnumerator();
-                foreach (KeyValuePair<T, int> p in t.ItemMultiplicities())
+                using (SCG.IEnumerator<KeyValuePair<T, int>> ie = ItemMultiplicities().GetEnumerator())
                 {
-                    //We know p.Key is in this!
-                    while (ie.MoveNext())
+                    foreach (KeyValuePair<T, int> p in t.ItemMultiplicities())
                     {
-                        if (comparer.Compare(ie.Current.Key, p.Key) == 0)
+                        //We know p.Key is in this!
+                        while (ie.MoveNext())
                         {
+                            if (comparer.Compare(ie.Current.Key, p.Key) == 0)
+                            {
 
-                            break;
+                                break;
+                            }
+                            else
+                                wasRemoved.Enqueue(ie.Current);
                         }
-                        else
-                            wasRemoved.Enqueue(ie.Current);
                     }
+                    while (ie.MoveNext())
+                        wasRemoved.Enqueue(ie.Current);
                 }
-                while (ie.MoveNext())
-                    wasRemoved.Enqueue(ie.Current);
             }
 
             root = t.root;
@@ -1971,50 +1976,52 @@ namespace Lucene.Net.Support
             if (!isValid)
                 throw new ViewDisposedException("Snapshot has been disposed");
             TreeSet<T> res = new TreeSet<T>(comparer);
-            SCG.IEnumerator<T> e = GetEnumerator();
-            Node head = null, tail = null;
-            int z = 0;
-
-            while (e.MoveNext())
+            using (SCG.IEnumerator<T> e = GetEnumerator())
             {
-                T thisitem = e.Current;
+                Node head = null, tail = null;
+                int z = 0;
 
-                if (filter(thisitem))
+                while (e.MoveNext())
                 {
-                    if (head == null)
-                    {
-                        head = tail = new Node();
-                    }
-                    else
+                    T thisitem = e.Current;
+
+                    if (filter(thisitem))
                     {
+                        if (head == null)
+                        {
+                            head = tail = new Node();
+                        }
+                        else
+                        {
 
-                        tail.right = new Node();
-                        tail = tail.right;
-                    }
+                            tail.right = new Node();
+                            tail = tail.right;
+                        }
 
-                    tail.item = thisitem;
-                    z++;
+                        tail.item = thisitem;
+                        z++;
+                    }
                 }
-            }
 
 
-            if (z == 0)
-                return res;
+                if (z == 0)
+                    return res;
 
-            int blackheight = 0, red = z, maxred = 1;
+                int blackheight = 0, red = z, maxred = 1;
 
-            while (maxred <= red)
-            {
-                red -= maxred;
-                maxred <<= 1;
-                blackheight++;
-            }
+                while (maxred <= red)
+                {
+                    red -= maxred;
+                    maxred <<= 1;
+                    blackheight++;
+                }
 
-            res.root = TreeSet<T>.maketreer(ref head, blackheight, maxred, red);
-            res.blackdepth = blackheight;
-            res.size = z;
+                res.root = TreeSet<T>.maketreer(ref head, blackheight, maxred, red);
+                res.blackdepth = blackheight;
+                res.size = z;
 
-            return res;
+                return res;
+            }
         }
 
 
@@ -2037,52 +2044,55 @@ namespace Lucene.Net.Support
             if (size == 0)
                 return res;
 
-            SCG.IEnumerator<T> e = GetEnumerator();
-            TreeSet<V>.Node head = null, tail = null;
-            V oldv = default(V);
-            int z = 0;
-
-            while (e.MoveNext())
+            using (SCG.IEnumerator<T> e = GetEnumerator())
             {
-                T thisitem = e.Current;
+                TreeSet<V>.Node head = null, tail = null;
+                V oldv = default(V);
+                int z = 0;
 
-                V newv = mapper(thisitem);
-
-                if (head == null)
+                while (e.MoveNext())
                 {
-                    head = tail = new TreeSet<V>.Node();
-                    z++;
-                }
-                else
-                {
-                    int comp = c.Compare(oldv, newv);
+                    T thisitem = e.Current;
+
+                    V newv = mapper(thisitem);
 
-                    if (comp >= 0)
+                    if (head == null)
+                    {
+                        head = tail = new TreeSet<V>.Node();
+                        z++;
+                    }
+                    else
+                    {
+                        int comp = c.Compare(oldv, newv);
 
-                        throw new ArgumentException("mapper not monotonic");
+                        if (comp >= 0)
 
-                    tail.right = new TreeSet<V>.Node();
-                    tail = tail.right;
-                    z++;
+                            throw new ArgumentException("mapper not monotonic");
+
+                        tail.right = new TreeSet<V>.Node();
+                        tail = tail.right;
+                        z++;
+                    }
+
+                    tail.item = oldv = newv;
                 }
 
-                tail.item = oldv = newv;
-            }
 
 
-            int blackheight = 0, red = z, maxred = 1;
+                int blackheight = 0, red = z, maxred = 1;
 
-            while (maxred <= red)
-            {
-                red -= maxred;
-                maxred <<= 1;
-                blackheight++;
-            }
+                while (maxred <= red)
+                {
+                    red -= maxred;
+                    maxred <<= 1;
+                    blackheight++;
+                }
 
-            res.root = TreeSet<V>.maketreer(ref head, blackheight, maxred, red);
-            res.blackdepth = blackheight;
-            res.size = size;
-            return res;
+                res.root = TreeSet<V>.maketreer(ref head, blackheight, maxred, red);
+                res.blackdepth = blackheight;
+                res.size = size;
+                return res;
+            }
         }
 
 
diff --git a/src/Lucene.Net/Util/AttributeSource.cs b/src/Lucene.Net/Util/AttributeSource.cs
index b46386a..f3b8b66 100644
--- a/src/Lucene.Net/Util/AttributeSource.cs
+++ b/src/Lucene.Net/Util/AttributeSource.cs
@@ -407,16 +407,18 @@ namespace Lucene.Net.Util
                 return s;
             }
             var c = s = currentState[0] = new State();
-            var it = attributeImpls.Values().GetEnumerator();
-            it.MoveNext();
-            c.attribute = it.Current.Value;
-            while (it.MoveNext())
+            using (var it = attributeImpls.Values().GetEnumerator())
             {
-                c.next = new State();
-                c = c.next;
+                it.MoveNext();
                 c.attribute = it.Current.Value;
+                while (it.MoveNext())
+                {
+                    c.next = new State();
+                    c = c.next;
+                    c.attribute = it.Current.Value;
+                }
+                return s;
             }
-            return s;
         }
 
         /// <summary>
diff --git a/src/Lucene.Net/Util/Automaton/BasicOperations.cs b/src/Lucene.Net/Util/Automaton/BasicOperations.cs
index d6efcb9..6169edc 100644
--- a/src/Lucene.Net/Util/Automaton/BasicOperations.cs
+++ b/src/Lucene.Net/Util/Automaton/BasicOperations.cs
@@ -3,6 +3,7 @@ using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Linq;
 using System.Text;
 
 /*
@@ -1034,9 +1035,7 @@ namespace Lucene.Net.Util.Automaton
             }
             if (a.initial.accept && a.initial.NumTransitions == 1)
             {
-                var iter = a.initial.GetTransitions().GetEnumerator();
-                iter.MoveNext();
-                Transition t = iter.Current; ;
+                Transition t = a.initial.GetTransitions().First();
                 return t.to == a.initial && t.min == Character.MIN_CODE_POINT && t.max == Character.MAX_CODE_POINT;
             }
             return false;
diff --git a/src/Lucene.Net/Util/Automaton/LevenshteinAutomata.cs b/src/Lucene.Net/Util/Automaton/LevenshteinAutomata.cs
index f6e82f7..94ce273 100644
--- a/src/Lucene.Net/Util/Automaton/LevenshteinAutomata.cs
+++ b/src/Lucene.Net/Util/Automaton/LevenshteinAutomata.cs
@@ -80,11 +80,13 @@ namespace Lucene.Net.Util.Automaton
                 set.Add(v);
             }
             alphabet = new int[set.Count];
-            IEnumerator<int> iterator = set.GetEnumerator();
-            for (int i = 0; i < alphabet.Length; i++)
+            using (IEnumerator<int> iterator = set.GetEnumerator())
             {
-                iterator.MoveNext();
-                alphabet[i] = iterator.Current;
+                for (int i = 0; i < alphabet.Length; i++)
+                {
+                    iterator.MoveNext();
+                    alphabet[i] = iterator.Current;
+                }
             }
 
             rangeLower = new int[alphabet.Length + 2];
diff --git a/src/Lucene.Net/Util/Automaton/SpecialOperations.cs b/src/Lucene.Net/Util/Automaton/SpecialOperations.cs
index b312fb9..17b83cf 100644
--- a/src/Lucene.Net/Util/Automaton/SpecialOperations.cs
+++ b/src/Lucene.Net/Util/Automaton/SpecialOperations.cs
@@ -124,9 +124,7 @@ namespace Lucene.Net.Util.Automaton
                 visited.Add(s);
                 if (!s.accept && s.NumTransitions == 1)
                 {
-                    var iter = s.GetTransitions().GetEnumerator();
-                    iter.MoveNext();
-                    Transition t = iter.Current;
+                    Transition t = s.GetTransitions().First();
                     if (t.min == t.max && !visited.Contains(t.to))
                     {
                         b.AppendCodePoint(t.min);
@@ -157,9 +155,7 @@ namespace Lucene.Net.Util.Automaton
                 visited.Add(s);
                 if (!s.accept && s.NumTransitions == 1)
                 {
-                    var iter = s.GetTransitions().GetEnumerator();
-                    iter.MoveNext();
-                    Transition t = iter.Current;
+                    Transition t = s.GetTransitions().First();
 
                     if (t.min == t.max && !visited.Contains(t.to))
                     {
diff --git a/src/Lucene.Net/Util/CloseableThreadLocal.cs b/src/Lucene.Net/Util/CloseableThreadLocal.cs
index 0328a4a..706334d 100644
--- a/src/Lucene.Net/Util/CloseableThreadLocal.cs
+++ b/src/Lucene.Net/Util/CloseableThreadLocal.cs
@@ -122,9 +122,8 @@ namespace Lucene.Net.Util
                 List<Thread> Removed = new List<Thread>();
                 try
                 {
-                    for (IEnumerator<Thread> it = hardRefs.Keys.GetEnumerator(); it.MoveNext(); )
+                    foreach (Thread t in hardRefs.Keys)
                     {
-                        Thread t = it.Current;
                         if (!t.IsAlive)
                         {
                             Removed.Add(t);
diff --git a/src/Lucene.Net/Util/MergedIterator.cs b/src/Lucene.Net/Util/MergedIterator.cs
index 668bfdf..7ee721c 100644
--- a/src/Lucene.Net/Util/MergedIterator.cs
+++ b/src/Lucene.Net/Util/MergedIterator.cs
@@ -43,9 +43,12 @@ namespace Lucene.Net.Util
     ///       are returned isn't defined.</description></item>
     /// </list>
     /// <para/>
+    /// The caller is responsible for disposing the <see cref="IEnumerator{T}"/> instances that are passed
+    /// into the constructor, <see cref="MergedIterator{T}"/> doesn't do it automatically.
+    /// <para/>
     /// @lucene.internal
     /// </summary>
-    public sealed class MergedIterator<T> : IEnumerator<T>
+    public sealed class MergedIterator<T> : IEnumerator<T> // LUCENENET TODO: API - rename MergedEnumerator
         where T : IComparable<T>
     {
         private readonly TermMergeQueue<T> queue;
diff --git a/src/Lucene.Net/Util/WAH8DocIdSet.cs b/src/Lucene.Net/Util/WAH8DocIdSet.cs
index b5abda8..c1470e0 100644
--- a/src/Lucene.Net/Util/WAH8DocIdSet.cs
+++ b/src/Lucene.Net/Util/WAH8DocIdSet.cs
@@ -2,6 +2,7 @@ using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Linq;
 
 namespace Lucene.Net.Util
 {
@@ -127,9 +128,7 @@ namespace Lucene.Net.Util
                 case 0:
                     throw new System.ArgumentException("There must be at least one set to intersect");
                 case 1:
-                    var iter = docIdSets.GetEnumerator();
-                    iter.MoveNext();
-                    return iter.Current;
+                    return docIdSets.First();
             }
             // The logic below is similar to ConjunctionScorer
             int numSets = docIdSets.Count;
@@ -202,9 +201,7 @@ namespace Lucene.Net.Util
                     return EMPTY;
 
                 case 1:
-                    var iter = docIdSets.GetEnumerator();
-                    iter.MoveNext();
-                    return iter.Current;
+                    return docIdSets.First();
             }
             // The logic below is very similar to DisjunctionScorer
             int numSets = docIdSets.Count;
diff --git a/src/dotnet/tools/lucene-cli/SourceCode/ConsolePager.cs b/src/dotnet/tools/lucene-cli/SourceCode/ConsolePager.cs
index ef17101..71d3f16 100644
--- a/src/dotnet/tools/lucene-cli/SourceCode/ConsolePager.cs
+++ b/src/dotnet/tools/lucene-cli/SourceCode/ConsolePager.cs
@@ -51,7 +51,7 @@ namespace Lucene.Net.Cli.SourceCode
     ///     </item>
     /// </list>
     /// </summary>
-    public class ConsolePager : IDisposable
+    public sealed class ConsolePager : IDisposable
     {
         private readonly MultipleFileLineEnumerator enumerator;