diff --git a/applications/test/tokenize/Test-tokenize.C b/applications/test/tokenize/Test-tokenize.C
index 5c616cacb52b0a5b5e78d34186267d8b05df01f5..bd2f84a4820580915d6a71c308aa2f55050e7c0b 100644
--- a/applications/test/tokenize/Test-tokenize.C
+++ b/applications/test/tokenize/Test-tokenize.C
@@ -41,22 +41,28 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
+    argList::noBanner();
     argList::noParallel();
     argList::validArgs.insert("string .. stringN");
     argList::addOption("file", "name");
     argList::addOption("repeat", "count");
+    argList::addBoolOption("verbose", "report for each repeat");
 
     argList args(argc, argv, false, true);
 
     const label repeat = args.optionLookupOrDefault<label>("repeat", 1);
 
+    const bool optVerbose = args.optionFound("verbose");
+
     cpuTime timer;
     for (label count = 0; count < repeat; ++count)
     {
+        const bool verbose = (optVerbose || count == 0);
+
         for (label argI=1; argI < args.size(); ++argI)
         {
             const string& rawArg = args[argI];
-            if (count == 0)
+            if (verbose)
             {
                 Info<< "input string: " << rawArg << nl;
             }
@@ -71,14 +77,15 @@ int main(int argc, char *argv[])
                 // is.putback(ch);
                 int lookahead = is.peek();
 
-                if (count == 0)
+                if (verbose)
                 {
-                    Info<< "token: " << tok.info();
-                    Info<< "  lookahead: '" << char(lookahead) << "'" << endl;
+                    Info<< "token: " << tok.info()
+                        << "  lookahead: '" << char(lookahead) << "'"
+                        << endl;
                 }
             }
 
-            if (count == 0)
+            if (verbose)
             {
                 Info<< nl;
                 IOobject::writeDivider(Info);
@@ -89,31 +96,44 @@ int main(int argc, char *argv[])
     Info<< "tokenized args " << repeat << " times in "
         << timer.cpuTimeIncrement() << " s\n\n";
 
-    if (args.optionFound("file"))
+    fileName inputFile;
+    if (args.optionReadIfPresent("file", inputFile))
     {
+        IFstream is(inputFile);
+
         for (label count = 0; count < repeat; ++count)
         {
-            IFstream is(args["file"]);
+            const bool verbose = (optVerbose || count == 0);
+            label nTokens = 0;
 
-            if (count == 0)
+            if (count)
             {
-                Info<< "tokenizing file: " << args["file"] << nl;
+                is.rewind();
             }
 
+            Info<< nl
+                << "tokenizing file (pass #" << (count+1) << ") "
+                << inputFile << nl
+                << "state: " << is.info() << endl;
+
             while (is.good())
             {
                 token tok(is);
-                if (count == 0)
+                if (verbose)
                 {
                     Info<< "token: " << tok.info() << endl;
                 }
+                ++nTokens;
             }
 
-            if (count == 0)
+            if (verbose)
             {
                 Info<< nl;
                 IOobject::writeDivider(Info);
             }
+
+            Info<<"pass #" << (count+1)
+                << " extracted " << nTokens << " tokens" << endl;
         }
 
         Info<< "tokenized file " << repeat << " times in "
diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C
index 08b833a5f3de30e23af57e4ad12ef204807fcbf4..fd3889618ea47660ed761cb72e81277653730c61 100644
--- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C
+++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C
@@ -167,6 +167,39 @@ const std::istream& Foam::IFstream::stdStream() const
 }
 
 
+Foam::Istream& Foam::IFstream::rewind()
+{
+    lineNumber_ = 1;      // Reset line number
+
+    igzstream* gzPtr = nullptr;
+
+    try
+    {
+        gzPtr = dynamic_cast<igzstream*>(allocatedPtr_);
+    }
+    catch (std::bad_cast)
+    {
+        gzPtr = nullptr;
+    }
+
+    if (gzPtr)
+    {
+        // Need special treatment for gzstream.
+        gzPtr->close();
+        gzPtr->clear();
+        gzPtr->open((this->name() + ".gz").c_str());
+
+        setState(gzPtr->rdstate());
+    }
+    else
+    {
+        ISstream::rewind();
+    }
+
+    return *this;
+}
+
+
 void Foam::IFstream::print(Ostream& os) const
 {
     os  << "IFstream: ";
diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H
index 658698f6b229e6528dde689b87eb9cb76f59b2fe..72f89873c58a92447f7de8320ceac5609d0ee7d5 100644
--- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H
+++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H
@@ -129,6 +129,9 @@ public:
         //- Const access to underlying std::istream
         virtual const std::istream& stdStream() const;
 
+        //- Rewind the stream so that it may be read again
+        virtual Istream& rewind();
+
 
       // Print
 
diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
index 750365b10496d0dae8d80452e991be16cb3bbf0f..7bd031d87a49e4a8ea70fa85971aeaed675e2359 100644
--- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
+++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
@@ -799,6 +799,11 @@ Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count)
 
 Foam::Istream& Foam::ISstream::rewind()
 {
+    lineNumber_ = 1;      // Reset line number
+
+    stdStream().clear();  // Clear the iostate error state flags
+    setGood();            // Sync local copy of iostate
+
     // pubseekpos() rather than seekg() so that it works with gzstream
     stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);