[mathicgb] 322/393: Went through ALL source files to give them a common copyright header, to put everything in namespace mgb to avoid name clashes and to normalize header inclusion order of system versus non-system headers. Apparently there is a bug or some issue here somewhere that requires using ::std::X to refer to std::X. That was really fun. Yep.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:29 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch upstream
in repository mathicgb.

commit 0a6fe2a64af597135f3700fd4b1f09fdc31a6c76
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Mon May 13 22:27:10 2013 +0200

    Went through ALL source files to give them a common copyright header, to put everything in namespace mgb to avoid name clashes and to normalize header inclusion order of system versus non-system headers. Apparently there is a bug or some issue here somewhere that requires using ::std::X to refer to std::X. That was really fun. Yep.
---
 src/checksource/CheckSource.cpp     |   14 +-
 src/cli/CommonParams.cpp            |    6 +
 src/cli/CommonParams.hpp            |    6 +
 src/cli/GBAction.cpp                |    6 +
 src/cli/GBAction.hpp                |    5 +
 src/cli/GBCommonParams.cpp          |    6 +
 src/cli/GBCommonParams.hpp          |    5 +
 src/cli/GBMain.cpp                  |   22 +-
 src/cli/HelpAction.cpp              |    7 +-
 src/cli/HelpAction.hpp              |   28 +-
 src/cli/MatrixAction.cpp            |   24 +-
 src/cli/MatrixAction.hpp            |    5 +
 src/cli/SigGBAction.cpp             |   30 +-
 src/cli/SigGBAction.hpp             |    5 +
 src/mathicgb.cpp                    |    2 +
 src/mathicgb/Atomic.hpp             |   77 +-
 src/mathicgb/Basis.cpp              |    9 +-
 src/mathicgb/Basis.hpp              |   25 +-
 src/mathicgb/BjarkeGeobucket.cpp    |   11 +-
 src/mathicgb/BjarkeGeobucket.hpp    |   18 +-
 src/mathicgb/BjarkeGeobucket2.cpp   |   10 +-
 src/mathicgb/BjarkeGeobucket2.hpp   |   18 +-
 src/mathicgb/CFile.cpp              |   62 +-
 src/mathicgb/CFile.hpp              |   79 +-
 src/mathicgb/ChainedHashTable.cpp   |   11 +-
 src/mathicgb/ChainedHashTable.hpp   |   19 +-
 src/mathicgb/ClassicGBAlg.cpp       |   14 +-
 src/mathicgb/ClassicGBAlg.hpp       |    5 +
 src/mathicgb/DivLookup.hpp          |   19 +-
 src/mathicgb/DivisorLookup.cpp      |   13 +-
 src/mathicgb/DivisorLookup.hpp      |   27 +-
 src/mathicgb/F4MatrixBuilder.cpp    |   44 +-
 src/mathicgb/F4MatrixBuilder.hpp    |  320 +--
 src/mathicgb/F4MatrixBuilder2.cpp   |   60 +-
 src/mathicgb/F4MatrixBuilder2.hpp   |  289 +--
 src/mathicgb/F4MatrixProjection.cpp |   68 +-
 src/mathicgb/F4MatrixProjection.hpp |   14 +-
 src/mathicgb/F4MatrixReducer.cpp    |   73 +-
 src/mathicgb/F4MatrixReducer.hpp    |   84 +-
 src/mathicgb/F4ProtoMatrix.cpp      |   26 +-
 src/mathicgb/F4ProtoMatrix.hpp      |   13 +-
 src/mathicgb/F4Reducer.cpp          |   70 +-
 src/mathicgb/F4Reducer.hpp          |   11 +-
 src/mathicgb/FixedSizeMonomialMap.h |   66 +-
 src/mathicgb/HashTourReducer.cpp    |   12 +-
 src/mathicgb/HashTourReducer.hpp    |   16 +-
 src/mathicgb/KoszulQueue.cpp        |    7 -
 src/mathicgb/KoszulQueue.hpp        |    9 +-
 src/mathicgb/LogDomain.cpp          |  224 +-
 src/mathicgb/LogDomain.hpp          |  664 +++---
 src/mathicgb/LogDomainSet.cpp       |    6 +
 src/mathicgb/LogDomainSet.hpp       |  185 +-
 src/mathicgb/MTArray.cpp            |    9 +-
 src/mathicgb/MTArray.hpp            |   16 +-
 src/mathicgb/MathicIO.cpp           |  752 +++----
 src/mathicgb/MathicIO.hpp           |  287 +--
 src/mathicgb/MonTableDivList.hpp    |   17 +-
 src/mathicgb/MonTableKDTree.hpp     |   15 +-
 src/mathicgb/MonTableNaive.cpp      |   14 +-
 src/mathicgb/MonTableNaive.hpp      |   19 +-
 src/mathicgb/MonoMonoid.hpp         | 4023 ++++++++++++++++++-----------------
 src/mathicgb/MonoOrder.hpp          |   17 +-
 src/mathicgb/MonoProcessor.hpp      |  267 +--
 src/mathicgb/MonomialHashTable.hpp  |   14 +-
 src/mathicgb/MonomialMap.hpp        |   41 +-
 src/mathicgb/NonCopyable.hpp        |   49 +-
 src/mathicgb/PairTriangle.cpp       |    6 +
 src/mathicgb/PairTriangle.hpp       |   31 +-
 src/mathicgb/Poly.cpp               |   13 +-
 src/mathicgb/Poly.hpp               |   53 +-
 src/mathicgb/PolyBasis.cpp          |    8 +-
 src/mathicgb/PolyBasis.hpp          |   27 +-
 src/mathicgb/PolyGeoBucket.cpp      |   12 +-
 src/mathicgb/PolyGeoBucket.hpp      |   17 +-
 src/mathicgb/PolyHashReducer.cpp    |   11 +-
 src/mathicgb/PolyHashReducer.hpp    |   16 +-
 src/mathicgb/PolyHashTable.cpp      |   10 +-
 src/mathicgb/PolyHashTable.hpp      |   23 +-
 src/mathicgb/PolyHeap.cpp           |   10 +-
 src/mathicgb/PolyHeap.hpp           |   16 +-
 src/mathicgb/PolyReducer.cpp        |   10 +-
 src/mathicgb/PolyReducer.hpp        |   16 +-
 src/mathicgb/PolyRing.cpp           |   10 +-
 src/mathicgb/PolyRing.hpp           |   41 +-
 src/mathicgb/PrimeField.hpp         |   29 +-
 src/mathicgb/QuadMatrix.cpp         |   58 +-
 src/mathicgb/QuadMatrix.hpp         |   33 +-
 src/mathicgb/QuadMatrixBuilder.cpp  |  260 +--
 src/mathicgb/QuadMatrixBuilder.hpp  |  403 ++--
 src/mathicgb/RawVector.hpp          |  619 +++---
 src/mathicgb/Reducer.cpp            |   10 +-
 src/mathicgb/Reducer.hpp            |   16 +-
 src/mathicgb/ReducerDedup.hpp       |   20 +-
 src/mathicgb/ReducerHash.hpp        |   21 +-
 src/mathicgb/ReducerHashPack.hpp    |   21 +-
 src/mathicgb/ReducerHelper.hpp      |   14 +-
 src/mathicgb/ReducerNoDedup.hpp     |   20 +-
 src/mathicgb/ReducerPack.hpp        |   19 +-
 src/mathicgb/ReducerPackDedup.hpp   |   20 +-
 src/mathicgb/SPairs.cpp             |    6 +
 src/mathicgb/SPairs.hpp             |   45 +-
 src/mathicgb/Scanner.cpp            |    6 +
 src/mathicgb/Scanner.hpp            |    5 +
 src/mathicgb/ScopeExit.hpp          |  202 +-
 src/mathicgb/SigPolyBasis.cpp       |    7 +-
 src/mathicgb/SigPolyBasis.hpp       |    8 +-
 src/mathicgb/SigSPairQueue.cpp      |   47 +-
 src/mathicgb/SigSPairQueue.hpp      |  151 +-
 src/mathicgb/SigSPairs.cpp          |   10 +-
 src/mathicgb/SigSPairs.hpp          |   15 +-
 src/mathicgb/SignatureGB.cpp        |   10 +-
 src/mathicgb/SignatureGB.hpp        |   16 +-
 src/mathicgb/SparseMatrix.cpp       |   68 +-
 src/mathicgb/SparseMatrix.hpp       |   64 +-
 src/mathicgb/TournamentReducer.cpp  |   12 +-
 src/mathicgb/TournamentReducer.hpp  |   16 +-
 src/mathicgb/TypicalReducer.cpp     |  462 ++--
 src/mathicgb/TypicalReducer.hpp     |  148 +-
 src/mathicgb/Unchar.hpp             |   82 +-
 src/mathicgb/io-util.cpp            |   83 +-
 src/mathicgb/io-util.hpp            |   47 +-
 src/mathicgb/mtbb.hpp               |  368 ++--
 src/mathicgb/stdinc.h               |   14 +
 src/test/F4MatrixBuilder.cpp        |  360 ++--
 src/test/F4MatrixReducer.cpp        |  256 +--
 src/test/MathicIO.cpp               |  630 +++---
 src/test/MonoMonoid.cpp             | 1733 +++++++--------
 src/test/PrimeField.cpp             |    6 +-
 src/test/QuadMatrixBuilder.cpp      |  492 ++---
 src/test/Scanner.cpp                |  244 +--
 src/test/SparseMatrix.cpp           |  175 +-
 src/test/gb-test.cpp                |   12 +-
 src/test/gtestInclude.cpp           |   27 +-
 src/test/ideals.cpp                 |  679 +++---
 src/test/ideals.hpp                 |  135 +-
 src/test/mathicgb.cpp               | 1118 +++++-----
 src/test/monoidPict.in              |   58 +-
 src/test/monoidPict.seed            |   18 +-
 src/test/pict.in                    |  116 +-
 src/test/poly-test.cpp              |   23 +-
 src/test/testMain.cpp               |    6 +
 141 files changed, 9306 insertions(+), 8956 deletions(-)

diff --git a/src/checksource/CheckSource.cpp b/src/checksource/CheckSource.cpp
index 94773c5..3440b78 100755
--- a/src/checksource/CheckSource.cpp
+++ b/src/checksource/CheckSource.cpp
@@ -57,13 +57,14 @@ void checkCopyrightHeader(Scanner& in) {
     "MathicGB comes with ABSOLUTELY\n";
   const char* const l2 =
     "// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.\n";
-  in.match(l1);
-  in.match(l2);
+  in.expect(l1);
+  in.expect(l2);
 }
 
 void checkStdInc(Scanner& in) {
   in.eatWhite();
-  in.expect("#include \"stdinc.h\"");
+  if (!in.match("#include \"mathicgb/stdinc.h\"\n"))
+      in.expect("#include \"stdinc.h\"\n");
 }
 
 void checkIncludes(Scanner& in) {
@@ -113,6 +114,9 @@ void checkInclusionGuard(Scanner& in, const std::string& filename) {
 
 void checkOther(const std::string& filename) {
   std::ifstream file(filename.c_str(), std::ios_base::binary);
+  file.peek();
+  if (!file)
+    error("could not open file");
   Scanner in(file);
   bool mgbNamespace = false;
   while (!in.matchEOF()) {
@@ -142,6 +146,7 @@ void checkFile(std::string filename) {
     const bool cpp = endsWith(filename, ".cpp");
     if (!hpp && !cpp)
       return;
+    checkOther(filename);
 
     std::ifstream file(filename.c_str());
     if (!file)
@@ -162,9 +167,6 @@ void checkFile(std::string filename) {
     else
       checkInclusionGuard(in, filename);
     checkIncludes(in);
-    file.close();
-
-    checkOther(filename);
   } catch (std::exception& e) {
     std::cout << "*** ERROR in file " << filename << " ***\n"
       << e.what() << std::endl;
diff --git a/src/cli/CommonParams.cpp b/src/cli/CommonParams.cpp
index 8413491..29e7786 100755
--- a/src/cli/CommonParams.cpp
+++ b/src/cli/CommonParams.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
 #include "CommonParams.hpp"
 
@@ -6,6 +8,8 @@
 
 MATHICGB_DEFINE_LOG_ALIAS("default", "F4Detail,SPairs");
 
+MATHICGB_NAMESPACE_BEGIN
+
 CommonParams::CommonParams(size_t minDirectParams, size_t maxDirectParams):
   mTracingLevel("tracingLevel",
     "How much information to print out about what the program does. No "
@@ -99,3 +103,5 @@ std::string CommonParams::inputFileNameExtension(size_t i) {
   }
   return std::string();
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/cli/CommonParams.hpp b/src/cli/CommonParams.hpp
old mode 100644
new mode 100755
index 9843706..9357eff
--- a/src/cli/CommonParams.hpp
+++ b/src/cli/CommonParams.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_COMMON_PARAMS_GUARD
 #define MATHICGB_COMMON_PARAMS_GUARD
 
@@ -5,6 +7,8 @@
 #include <mathic.h>
 #include <vector>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class CommonParams {
 public:
   CommonParams(size_t minDirectParams, size_t maxDirectParams);
@@ -50,4 +54,6 @@ private:
   std::vector<std::string> mDirectParameters;
 };
 
+MATHICGB_NAMESPACE_END
+
 #endif
diff --git a/src/cli/GBAction.cpp b/src/cli/GBAction.cpp
index 2aa818a..feaef86 100755
--- a/src/cli/GBAction.cpp
+++ b/src/cli/GBAction.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
 #include "GBAction.hpp"
 
@@ -10,6 +12,8 @@
 #include <fstream>
 #include <iostream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 GBAction::GBAction():
   mAutoTailReduce("autoTailReduce",
     "Reduce the non-leading terms of all polynomials whenever an element "
@@ -136,3 +140,5 @@ void GBAction::pushBackParameters(
   parameters.push_back(&mSPairGroupSize);
   parameters.push_back(&mMinMatrixToStore);
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/cli/GBAction.hpp b/src/cli/GBAction.hpp
old mode 100644
new mode 100755
index 83849ff..4afbe0a
--- a/src/cli/GBAction.hpp
+++ b/src/cli/GBAction.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_G_B_ACTION_GUARD
 #define MATHICGB_G_B_ACTION_GUARD
 
@@ -5,6 +7,8 @@
 #include "CommonParams.hpp"
 #include <mathic.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 /// Calculates a classic Grobner basis using Buchberger's algorithm
 class GBAction : public mathic::Action {
 public:
@@ -35,4 +39,5 @@ private:
   mathic::IntegerParameter mMinMatrixToStore;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/cli/GBCommonParams.cpp b/src/cli/GBCommonParams.cpp
index b2b4079..f541742 100755
--- a/src/cli/GBCommonParams.cpp
+++ b/src/cli/GBCommonParams.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
 #include "GBCommonParams.hpp"
 
@@ -5,6 +7,8 @@
 #include "mathicgb/PolyReducer.hpp"
 #include "mathicgb/DivisorLookup.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 GBCommonParams::GBCommonParams():
   mPreferSparseReducers("preferSparseReducers",
     "If true, always use the sparsest reducer in polynomial reduction. "
@@ -88,3 +92,5 @@ void GBCommonParams::pushBackParameters(
 void GBCommonParams::perform() {
   // currently there is nothing to do
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/cli/GBCommonParams.hpp b/src/cli/GBCommonParams.hpp
index 04a4cfd..65441a5 100755
--- a/src/cli/GBCommonParams.hpp
+++ b/src/cli/GBCommonParams.hpp
@@ -1,8 +1,12 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_GB_COMMON_PARAMS_GUARD
 #define MATHICGB_GB_COMMON_PARAMS_GUARD
 
 #include <mathic.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class GBCommonParams {
 public:
   GBCommonParams();
@@ -21,4 +25,5 @@ public:
   mathic::IntegerParameter mMemoryQuantum;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/cli/GBMain.cpp b/src/cli/GBMain.cpp
index e94f4c0..4c052a4 100755
--- a/src/cli/GBMain.cpp
+++ b/src/cli/GBMain.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
 
 #include "GBAction.hpp"
@@ -10,13 +12,18 @@
 #include <iostream>
 #include <exception>
 
+// This is to satisfy the code checker that requires every file to contain
+// these macroes.
+MATHICGB_NAMESPACE_BEGIN
+MATHICGB_NAMESPACE_END
+
 int main(int argc, char **argv) {
   try {
     mathic::CliParser parser;
-    parser.registerAction<SigGBAction>();
-    parser.registerAction<GBAction>();
-    parser.registerAction<MatrixAction>();
-    parser.registerAction<HelpAction>();
+    parser.registerAction<mgb::SigGBAction>();
+    parser.registerAction<mgb::GBAction>();
+    parser.registerAction<mgb::MatrixAction>();
+    parser.registerAction<mgb::HelpAction>();
 
     std::vector<std::string> commandLine(argv, argv + argc);
     commandLine.erase(commandLine.begin());
@@ -35,11 +42,6 @@ int main(int argc, char **argv) {
     throw;
   }
 
-  LogDomainSet::singleton().printReport(std::cerr);
+  mgb::LogDomainSet::singleton().printReport(std::cerr);
   return 0;
 };
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/cli/HelpAction.cpp b/src/cli/HelpAction.cpp
index 6dd4590..73620c8 100755
--- a/src/cli/HelpAction.cpp
+++ b/src/cli/HelpAction.cpp
@@ -1,11 +1,14 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
 #include "HelpAction.hpp"
 
 #include "mathicgb/LogDomain.hpp"
 #include "mathicgb/LogDomainSet.hpp"
-
 #include <iostream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 void HelpAction::performAction() {
   if (topic() != "logs") {
     mathic::HelpAction::performAction();
@@ -78,3 +81,5 @@ void HelpAction::performAction() {
     " all expands to all log names\n";
     "\n";
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/cli/HelpAction.hpp b/src/cli/HelpAction.hpp
index 5bba19c..d263143 100755
--- a/src/cli/HelpAction.hpp
+++ b/src/cli/HelpAction.hpp
@@ -1,11 +1,17 @@
-#ifndef MATHICGB_HELP_ACTION_GUARD
-#define MATHICGB_HELP_ACTION_GUARD
-
-#include <mathic.h>
-
-class HelpAction : public mathic::HelpAction {
-public:
-  virtual void performAction();
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_HELP_ACTION_GUARD
+#define MATHICGB_HELP_ACTION_GUARD
+
+#include <mathic.h>
+
+MATHICGB_NAMESPACE_BEGIN
+
+class HelpAction : public mathic::HelpAction {
+public:
+  virtual void performAction();
+};
+
+MATHICGB_NAMESPACE_END
+
+#endif
diff --git a/src/cli/MatrixAction.cpp b/src/cli/MatrixAction.cpp
old mode 100644
new mode 100755
index dd7c75f..d81b441
--- a/src/cli/MatrixAction.cpp
+++ b/src/cli/MatrixAction.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
 #include "MatrixAction.hpp"
 
@@ -11,6 +13,8 @@
 #include <fstream>
 #include <iostream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 namespace {
   static const char* QuadMatrixExtension = ".qmat";
   static const char* LowerRightMatrixExtension = ".brmat";
@@ -24,13 +28,13 @@ namespace {
   /// portable. There could be a solution with freopen, but unfortunately
   /// freopen is allowed to fail on any change to the mode so it is not
   /// a portable solution.
-  bool fileExists(const std::string fileName) {
+  bool fileExists(const ::std::string fileName) {
     return CFile(fileName, "r", CFile::NoThrowTag()).hasFile();
   }
 }
 
 MatrixAction::MatrixAction():
-  mParams(1, std::numeric_limits<size_t>::max()) {
+  mParams(1, ::std::numeric_limits<size_t>::max()) {
   mParams.registerFileNameExtension(QuadMatrixExtension);
   mParams.registerFileNameExtension(LowerRightMatrixExtension);
   mParams.registerFileNameExtension(ReducedLowerRightMatrixExtension);
@@ -38,7 +42,7 @@ MatrixAction::MatrixAction():
 }
 
 void MatrixAction::directOptions(
-  std::vector<std::string> tokens,
+  ::std::vector< ::std::string> tokens,
   mic::CliParser& parser
 ) {
   mParams.directOptions(tokens, parser);
@@ -53,7 +57,7 @@ void MatrixAction::performAction() {
     const auto lowerRightFileName = fileNameStem + LowerRightMatrixExtension;
     const auto reducedLowerRightFileName =
       fileNameStem + ReducedLowerRightMatrixExtension;
-    std::string inputFileName;
+    ::std::string inputFileName;
 
     SparseMatrix lowerRightMatrix;
     SparseMatrix::Scalar modulus;
@@ -99,10 +103,10 @@ void MatrixAction::performAction() {
       referenceMatrix.read(file.handle());
 
       if (lowerRightMatrix != referenceMatrix) {
-        const std::string wrongFile =
+        const ::std::string wrongFile =
           fileNameStem + ".out" + ReducedLowerRightMatrixExtension;
-        const std::string wrongFilePbm = fileNameStem + ".out.pbm";
-        std::cerr << "Reducing " << inputFileName
+        const ::std::string wrongFilePbm = fileNameStem + ".out.pbm";
+        ::std::cerr << "Reducing " << inputFileName
           << " does not yield the matrix "
           << reducedLowerRightFileName << ".\n"
           << "Writing computed matrix to " << wrongFile << ".\n";
@@ -111,7 +115,7 @@ void MatrixAction::performAction() {
         CFile filePbm(wrongFilePbm, "wb");
         lowerRightMatrix.writePBM(filePbm.handle());
       } else if (tracingLevel > 0) {
-        std::cerr << "Match for " << inputFileName 
+        ::std::cerr << "Match for " << inputFileName 
           << " -> " << ReducedLowerRightMatrixExtension << ".\n";
       }
     }
@@ -136,7 +140,9 @@ const char* MatrixAction::shortDescription() const {
 }
 
 void MatrixAction::pushBackParameters(
-  std::vector<mic::CliParameter*>& parameters
+  ::std::vector<mic::CliParameter*>& parameters
 ) {
   mParams.pushBackParameters(parameters);
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/cli/MatrixAction.hpp b/src/cli/MatrixAction.hpp
old mode 100644
new mode 100755
index 7156454..31c6147
--- a/src/cli/MatrixAction.hpp
+++ b/src/cli/MatrixAction.hpp
@@ -1,9 +1,13 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_MATRIX_ACTION_GUARD
 #define MATHICGB_MATRIX_ACTION_GUARD
 
 #include "CommonParams.hpp"
 #include <mathic.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 /// Performs computations on matrices.
 class MatrixAction : public mathic::Action {
 public:
@@ -28,4 +32,5 @@ private:
   CommonParams mParams;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/cli/SigGBAction.cpp b/src/cli/SigGBAction.cpp
index 14eaee6..a18a587 100755
--- a/src/cli/SigGBAction.cpp
+++ b/src/cli/SigGBAction.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
 #include "SigGBAction.hpp"
 
@@ -9,6 +11,8 @@
 #include <fstream>
 #include <iostream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 SigGBAction::SigGBAction():
   mUseSingularCriterionEarly(
     "earlySingularCriterion",
@@ -30,7 +34,7 @@ SigGBAction::SigGBAction():
 {}
 
 void SigGBAction::directOptions(
-  std::vector<std::string> tokens,
+  ::std::vector< ::std::string> tokens,
   mic::CliParser& parser
 ) {
   mParams.directOptions(tokens, parser);
@@ -41,8 +45,8 @@ void SigGBAction::performAction() {
   mGBParams.perform();
 
   // read input file
-  const std::string inputBasisFile = mParams.inputFileNameStem(0) + ".ideal";
-  std::ifstream inputFile(inputBasisFile.c_str());
+  const ::std::string inputBasisFile = mParams.inputFileNameStem(0) + ".ideal";
+  ::std::ifstream inputFile(inputBasisFile.c_str());
   if (inputFile.fail())
     mic::reportError("Could not read input file \"" + inputBasisFile + '\n');
 
@@ -56,8 +60,8 @@ void SigGBAction::performAction() {
     processor.setSchreyerMultipliers(basis);
 
   SignatureGB alg(
-    std::move(basis),
-    std::move(processor),
+    ::std::move(basis),
+    ::std::move(processor),
     Reducer::reducerType(mGBParams.mReducer.value()),
     mGBParams.mDivisorLookup.value(),
     mGBParams.mMonomialTable.value(),
@@ -71,10 +75,10 @@ void SigGBAction::performAction() {
   alg.computeGrobnerBasis();
 
   // print statistics
-  alg.displayStats(std::cout);
-  alg.displayPaperStats(std::cout);
+  alg.displayStats(::std::cout);
+  alg.displayPaperStats(::std::cout);
   {
-    std::ofstream statsOut((mParams.inputFileNameStem(0) + ".stats").c_str());
+    ::std::ofstream statsOut((mParams.inputFileNameStem(0) + ".stats").c_str());
     alg.displayStats(statsOut);
     alg.displayPaperStats(statsOut);
   }
@@ -83,17 +87,17 @@ void SigGBAction::performAction() {
     {
       // print basis
       {
-        std::ofstream ogb((mParams.inputFileNameStem(0) + ".gb").c_str());
+        ::std::ofstream ogb((mParams.inputFileNameStem(0) + ".gb").c_str());
         ogb << "-- gb: ----\n";
         alg.getGB()->display(ogb);
       }
       
       // print syzygy basis
       {
-        std::ofstream syzygyOut((mParams.inputFileNameStem(0) + ".syz").c_str());
+        ::std::ofstream syzygyOut((mParams.inputFileNameStem(0) + ".syz").c_str());
         syzygyOut << "-- syz: ----\n";
         alg.getSyzTable()->display(syzygyOut, 1);
-        syzygyOut << std::endl;
+        syzygyOut << ::std::endl;
       }
     }
 }
@@ -116,7 +120,7 @@ const char* SigGBAction::shortDescription() const {
 }
 
 void SigGBAction::pushBackParameters(
-  std::vector<mic::CliParameter*>& parameters
+  ::std::vector<mic::CliParameter*>& parameters
 ) {
   mParams.pushBackParameters(parameters);
   mGBParams.pushBackParameters(parameters);
@@ -124,3 +128,5 @@ void SigGBAction::pushBackParameters(
   parameters.push_back(&mPostponeKoszul);
   parameters.push_back(&mUseBaseDivisors);
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/cli/SigGBAction.hpp b/src/cli/SigGBAction.hpp
index c25e199..5c0fae7 100755
--- a/src/cli/SigGBAction.hpp
+++ b/src/cli/SigGBAction.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_SIG_G_B_ACTION_GUARD
 #define MATHICGB_SIG_G_B_ACTION_GUARD
 
@@ -5,6 +7,8 @@
 #include "CommonParams.hpp"
 #include <mathic.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class SigGBAction : public mic::Action {
 public:
   SigGBAction();
@@ -32,4 +36,5 @@ private:
   mic::BoolParameter mUseBaseDivisors;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb.cpp b/src/mathicgb.cpp
index 4ff4b61..388cea5 100755
--- a/src/mathicgb.cpp
+++ b/src/mathicgb.cpp
@@ -10,6 +10,8 @@
 #include "mathicgb/LogDomainSet.hpp"
 #include <mathic.h>
 
+using namespace mgb;
+
 namespace {
   bool isPrime(unsigned int n) {
     if (n == 0 || n == 1)
diff --git a/src/mathicgb/Atomic.hpp b/src/mathicgb/Atomic.hpp
index 49c0690..aa5ef5f 100755
--- a/src/mathicgb/Atomic.hpp
+++ b/src/mathicgb/Atomic.hpp
@@ -1,10 +1,14 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_ATOMIC_GUARD
 #define MATHICGB_ATOMIC_GUARD
 
-// We need this include for std::memory_order even if we are not
-// using std::atomic.
+// We need this include for ::std::memory_order even if we are not
+// using ::std::atomic.
 #include <atomic>
 
+MATHICGB_NAMESPACE_BEGIN
+
 namespace AtomicInternal {
   /// Tells the compiler (not the CPU) to not reorder reads across this line.
   inline void compilerReadMemoryBarrier();
@@ -96,8 +100,8 @@ namespace AtomicInternal {
   public:
     FakeAtomic(): mValue() {}
     FakeAtomic(T value): mValue(value) {}
-    T load(const std::memory_order) const {return mValue;}
-    void store(const T value, const std::memory_order order) {mValue = value;}
+    T load(const ::std::memory_order) const {return mValue;}
+    void store(const T value, const ::std::memory_order order) {mValue = value;}
 
   private:
     T mValue;
@@ -110,11 +114,11 @@ namespace AtomicInternal {
 
 #else
   /// Class for deciding which implementation of atomic to use. The default is
-  /// to use std::atomic which is a fine choice if std::atomic is implemented
+  /// to use ::std::atomic which is a fine choice if ::std::atomic is implemented
   /// in a reasonable way by the standard library implementation you are using.
   template<class T, size_t size>
   struct ChooseAtomic {
-    typedef std::atomic<T> type;
+    typedef ::std::atomic<T> type;
   };
 #endif
 }
@@ -126,7 +130,7 @@ namespace AtomicInternal {
   /// writes are guaranteed to be atomic - this class only takes care of the
   /// ordering constraints using CPU and compiler fences. Since the directives
   /// to achieve this are coming from the compiler it is surprising that
-  /// any compiler ships with a std::atomic that is worse than this - but
+  /// any compiler ships with a ::std::atomic that is worse than this - but
   /// that is very much the case. Though implementing atomic load and store
   /// is very little code, as you can see, it is quite tricky and took me
   /// a long time to understand everything well enough to actually know what
@@ -182,9 +186,9 @@ namespace AtomicInternal {
     CustomAtomicX86X64(T value): mValue(value) {}
 
     MATHICGB_INLINE
-    T load(const std::memory_order order) const {
+    T load(const ::std::memory_order order) const {
       switch (order) {
-      case std::memory_order_relaxed:
+      case ::std::memory_order_relaxed:
         // There are two constraints for memory_order_relaxed. The first
         // constraint is that if you read *p, then you will never
         // after that read a value of *p that was stored before the value
@@ -199,7 +203,7 @@ namespace AtomicInternal {
         // this constraint is broken, but clearly the written value must turn
         // up eventually. This constraint could be broken in cases like this:
         //
-        //   while (x.load(std::memory_order_relaxed) == 0) {
+        //   while (x.load(::std::memory_order_relaxed) == 0) {
         //     // do something that does not write to x
         //   }
         //
@@ -208,7 +212,7 @@ namespace AtomicInternal {
         // the value for every iteration, so the code can safely be transformed
         // to:
         //
-        //   if (x.load(std::memory_order_relaxed) == 0) {
+        //   if (x.load(::std::memory_order_relaxed) == 0) {
         //     while (true) {
         //       // ...
         //     }
@@ -229,7 +233,7 @@ namespace AtomicInternal {
         // volatile read since it is the best choice on GCC.
         return const_cast<volatile T&>(mValue);
 
-      case std::memory_order_consume: {
+      case ::std::memory_order_consume: {
         // Loads in this thread that depend on the loaded value must not be
         // reordered to before this load. So no DLL reorderings past this
         // load from after to before (up). So we need a read barrier AFTER the
@@ -240,7 +244,7 @@ namespace AtomicInternal {
         return value;
       }
 
-      case std::memory_order_acquire: {
+      case ::std::memory_order_acquire: {
         // Loads in this thread must not be reordered to before this load.
         // So no LL reorderings past this load from after to before (up).
         // So we need a read barrier AFTER the load. It is a compiler only
@@ -250,35 +254,35 @@ namespace AtomicInternal {
         return value;
       }
 
-      case std::memory_order_seq_cst: {
+      case ::std::memory_order_seq_cst: {
         // There must be some global order in which all sequentially consistent
         // atomic operations are considered to have happened in. On x86 and x64
         // this is guaranteed by just a normal read as long as all writes use
         // locked instructions like XHCG. See: http://goo.gl/U8xTK
         //
         // We still need to prevent the compiler from reordering the reads,
-        // which is the same constraint as for std::memory_order_acquire.
+        // which is the same constraint as for ::std::memory_order_acquire.
         const auto value = mValue;
         compilerReadMemoryBarrier();
         return value;
       }
 
-      case std::memory_order_release: // not available for load
-      case std::memory_order_acq_rel: // not available for load
-      default: // specified value is not a known std::memory_order
+      case ::std::memory_order_release: // not available for load
+      case ::std::memory_order_acq_rel: // not available for load
+      default: // specified value is not a known ::std::memory_order
         MATHICGB_UNREACHABLE;
       }
     }
 
     MATHICGB_INLINE
-    void store(const T value, const std::memory_order order) {
+    void store(const T value, const ::std::memory_order order) {
       switch (order) {
-      case std::memory_order_relaxed:
+      case ::std::memory_order_relaxed:
         // There are no reordering constraints here but we need to tell the
         // compiler that it must actually write out the value to memory in
         // a scenario like this:
         //
-        //   x.store(1, std::memory_order_relaxed);
+        //   x.store(1, ::std::memory_order_relaxed);
         //   while (true) {}
         //
         // So as for relaxed store we need either a volatile access or a memory
@@ -287,7 +291,7 @@ namespace AtomicInternal {
         const_cast<volatile T&>(mValue) = value;
         break;
 
-      case std::memory_order_release:
+      case ::std::memory_order_release:
         // Stores in this thread must not be reordered to after this store.
         // So no SS reorderings past this load from before to after (down).
         // So we need a barrier BEFORE the load. It is a compiler only barrier
@@ -296,9 +300,9 @@ namespace AtomicInternal {
         mValue = value;
         break;
 
-      case std::memory_order_acq_rel:
-        // Combine the guarantees for std::memory_order_acquire and
-        // std::memory_order_release. So no loads moved up past here (SL) and
+      case ::std::memory_order_acq_rel:
+        // Combine the guarantees for ::std::memory_order_acquire and
+        // ::std::memory_order_release. So no loads moved up past here (SL) and
         // no stores moved down past here (LL). We need a compiler barrier
         // BEFORE the load to avoid LL and a CPU (+compiler) barrier AFTER the
         // load to avoid SL, since x86 and x64 CPUs can in fact do SL
@@ -308,14 +312,14 @@ namespace AtomicInternal {
         cpuReadWriteMemoryBarrier();
         break;
 
-      case std::memory_order_seq_cst:
+      case ::std::memory_order_seq_cst:
         // All operations happen in a globally consistent total order.
         seqCstStore(value, mValue);
         break;
 
-      case std::memory_order_consume: // not available for store
-      case std::memory_order_acquire: // not available for store
-      default: // specified value is not a known std::memory_order
+      case ::std::memory_order_consume: // not available for store
+      case ::std::memory_order_acquire: // not available for store
+      default: // specified value is not a known ::std::memory_order
         MATHICGB_UNREACHABLE;
       }
     }
@@ -340,18 +344,18 @@ namespace AtomicInternal {
 }
 #endif
 
-/// This class is equivalent to std::atomic<T>. Some functions from the
-/// interface of std::atomic are missing - add them as necessary. Do not add
+/// This class is equivalent to ::std::atomic<T>. Some functions from the
+/// interface of ::std::atomic are missing - add them as necessary. Do not add
 /// operator= and operator T() --- it is better to make the code explicit
 /// about when and how loading and storing of atomic variables occurs.
 ///
 /// The purpose of the class is that it performs far better than
-/// std::atomic for some implementations. For example the std::atomic in MSVC
+/// ::std::atomic for some implementations. For example the ::std::atomic in MSVC
 /// 2012 performs a compare-and-swap operation on a load even with the
-/// paramter std::memory_order_relaxed.
+/// paramter ::std::memory_order_relaxed.
 ///
 /// We force all the functions to be inline because they can contain switches
-/// on the value of std::memory_order. This will usually be a compile-time
+/// on the value of ::std::memory_order. This will usually be a compile-time
 /// constant parameter so that after inlining the switch will disappear. Yet
 /// the code size of the switch may make some compilers avoid the inline.
 template<class T>
@@ -361,7 +365,7 @@ public:
   Atomic(T value): mValue(value) {}
 
   MATHICGB_INLINE
-  T load(const std::memory_order order = std::memory_order_seq_cst) const {
+  T load(const ::std::memory_order order = ::std::memory_order_seq_cst) const {
     MATHICGB_ASSERT(debugAligned());
     return mValue.load(order);
   }
@@ -369,7 +373,7 @@ public:
   MATHICGB_INLINE
   void store(
     const T value,
-    const std::memory_order order = std::memory_order_seq_cst
+    const ::std::memory_order order = ::std::memory_order_seq_cst
   ) {
     MATHICGB_ASSERT(debugAligned());
     mValue.store(value, order);
@@ -386,4 +390,5 @@ private:
   typename AtomicInternal::ChooseAtomic<T, sizeof(T)>::type mValue;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/Basis.cpp b/src/mathicgb/Basis.cpp
index 9e3c201..e416afb 100755
--- a/src/mathicgb/Basis.cpp
+++ b/src/mathicgb/Basis.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "Basis.hpp"
 
@@ -9,6 +11,8 @@
 #include <iostream>
 #include <cctype>
 
+MATHICGB_NAMESPACE_BEGIN
+
 void Basis::insert(std::unique_ptr<Poly>&& p) {
   MATHICGB_ASSERT(p.get() != 0);
   MATHICGB_ASSERT(p->termsAreInDescendingOrder());
@@ -36,7 +40,4 @@ void Basis::display(std::ostream& out, bool printComponent, bool componentIncrea
   }
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/Basis.hpp b/src/mathicgb/Basis.hpp
index 3afbf11..44af198 100755
--- a/src/mathicgb/Basis.hpp
+++ b/src/mathicgb/Basis.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_BASIS_GUARD
 #define MATHICGB_BASIS_GUARD
 
@@ -8,6 +10,8 @@
 #include <algorithm>
 #include <vector>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class Poly;
 
 // Really: a list of polynomials
@@ -15,17 +19,22 @@ class Poly;
 class Basis {
 public:
   Basis(const PolyRing &R) : mRing(R) {}
-  Basis(Basis&& basis): mRing(basis.ring()), mGenerators(std::move(basis.mGenerators)) {}
+  Basis(Basis&& basis):
+    mRing(basis.ring()), mGenerators(::std::move(basis.mGenerators)) {}
 
-  void insert(std::unique_ptr<Poly>&& p);
+  void insert(::std::unique_ptr<Poly>&& p);
 
   /// inverse operation to parse().
-  void display(std::ostream &o, bool print_comp, bool componentIncreasingDesired) const;
+  void display(
+    ::std::ostream &o,
+    bool print_comp,
+    bool componentIncreasingDesired
+  ) const;
 
   const PolyRing& ring() const { return mRing; }
 
   const PolyRing *getPolyRing() const { return &mRing; }
-  const std::vector<std::unique_ptr<Poly>>& viewGenerators() {
+  const ::std::vector< ::std::unique_ptr<Poly>>& viewGenerators() {
     return mGenerators;
   }
   const Poly *getPoly(size_t i) const {
@@ -42,12 +51,8 @@ private:
   Basis(const Basis&); // not available
 
   const PolyRing& mRing;
-  std::vector<std::unique_ptr<Poly>> mGenerators;
+  ::std::vector< ::std::unique_ptr<Poly>> mGenerators;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/BjarkeGeobucket.cpp b/src/mathicgb/BjarkeGeobucket.cpp
old mode 100644
new mode 100755
index 9e27781..2937fdf
--- a/src/mathicgb/BjarkeGeobucket.cpp
+++ b/src/mathicgb/BjarkeGeobucket.cpp
@@ -1,8 +1,10 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "BjarkeGeobucket.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 BjarkeGeobucket::BjarkeGeobucket(const PolyRing *R0)
   : Reducer(),
     R_(R0),
@@ -127,7 +129,4 @@ void BjarkeGeobucket::dump() const
   H_.dump(0);
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/BjarkeGeobucket.hpp b/src/mathicgb/BjarkeGeobucket.hpp
index 35e638c..9fce567 100755
--- a/src/mathicgb/BjarkeGeobucket.hpp
+++ b/src/mathicgb/BjarkeGeobucket.hpp
@@ -1,11 +1,13 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_BJARKE_GEOBUCKET_GUARD
+#define MATHICGB_BJARKE_GEOBUCKET_GUARD
 
-#ifndef _bjarkeGeoBucket_h_
-#define _bjarkeGeoBucket_h_
-
-#include <mathic.h>
 #include "Reducer.hpp"
 #include "PolyHashTable.hpp"
+#include <mathic.h>
+
+MATHICGB_NAMESPACE_BEGIN
 
 template<
   bool TrackFront,
@@ -95,9 +97,5 @@ private:
   mic::Geobucket< Configuration > G_;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/BjarkeGeobucket2.cpp b/src/mathicgb/BjarkeGeobucket2.cpp
index 5468f74..61ef930 100755
--- a/src/mathicgb/BjarkeGeobucket2.cpp
+++ b/src/mathicgb/BjarkeGeobucket2.cpp
@@ -1,9 +1,12 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "BjarkeGeobucket2.hpp"
 
 #include <iostream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 BjarkeGeobucket2::BjarkeGeobucket2(const PolyRing *R0):
   mRing(*R0),
   mHashTableOLD(R0, 10),
@@ -125,7 +128,4 @@ void BjarkeGeobucket2::dump() const
   mHashTableOLD.dump(0);
 }
 
-// Local Variables:
-// compile-command: "make -C $MATHIC/mathicgb "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/BjarkeGeobucket2.hpp b/src/mathicgb/BjarkeGeobucket2.hpp
index 016a35a..2f4443c 100755
--- a/src/mathicgb/BjarkeGeobucket2.hpp
+++ b/src/mathicgb/BjarkeGeobucket2.hpp
@@ -1,11 +1,13 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_BJARKE_GEOBUCKET2_GUARD
+#define MATHICGB_BJARKE_GEOBUCKET2_GUARD
 
-#ifndef _bjarkeGeoBucket_h_
-#define _bjarkeGeoBucket_h_
-
-#include <mathic.h>
 #include "TypicalReducer.hpp"
 #include "PolyHashTable.hpp"
+#include <mathic.h>
+
+MATHICGB_NAMESPACE_BEGIN
 
 class GeoConfiguration {
 public:
@@ -105,9 +107,5 @@ private:
   mic::Geobucket< GeoConfiguration > mHeap;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// indent-tabs-mode: nil
-// compile-command: "make -C $MATHIC/mathicgb "
-// End:
diff --git a/src/mathicgb/CFile.cpp b/src/mathicgb/CFile.cpp
index b882aa0..025010d 100755
--- a/src/mathicgb/CFile.cpp
+++ b/src/mathicgb/CFile.cpp
@@ -1,28 +1,34 @@
-#include "stdinc.h"
-#include "CFile.hpp"
-
-#include <mathic.h>
-#include <sstream>
-
-CFile::CFile(const std::string& fileName, const char* mode, NoThrowTag):
-  mFile(fopen(fileName.c_str(), mode)
-) {}
-
-CFile::CFile(const std::string& fileName, const char* mode):
-  mFile(fopen(fileName.c_str(), mode)
-) {
-  if (mFile == 0) {
-    std::ostringstream error;
-    error << "Could not open file " << fileName << " in mode " << mode << '.';
-    mathic::reportError(error.str());
-  }
-}
-
-CFile::~CFile() {
-  close();
-}
-
-void CFile::close() {
-  if (mFile != 0)
-    fclose(mFile);
-}
\ No newline at end of file
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "stdinc.h"
+#include "CFile.hpp"
+
+#include <mathic.h>
+#include <sstream>
+
+MATHICGB_NAMESPACE_BEGIN
+
+CFile::CFile(const std::string& fileName, const char* mode, NoThrowTag):
+  mFile(fopen(fileName.c_str(), mode)
+) {}
+
+CFile::CFile(const std::string& fileName, const char* mode):
+  mFile(fopen(fileName.c_str(), mode)
+) {
+  if (mFile == 0) {
+    std::ostringstream error;
+    error << "Could not open file " << fileName << " in mode " << mode << '.';
+    mathic::reportError(error.str());
+  }
+}
+
+CFile::~CFile() {
+  close();
+}
+
+void CFile::close() {
+  if (mFile != 0)
+    fclose(mFile);
+}
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/CFile.hpp b/src/mathicgb/CFile.hpp
index 1474443..257e239 100755
--- a/src/mathicgb/CFile.hpp
+++ b/src/mathicgb/CFile.hpp
@@ -1,37 +1,42 @@
-#ifndef MATHICGB_C_FILE_GUARD
-#define MATHICGB_C_FILE_GUARD
-
-#include <string>
-#include <cstdio>
-
-/// RAII handle for a C FILE*.
-///
-/// The purpose of using the C IO interface instead of iostreams is that the
-/// former is faster to a ridiculous degree. This class wraps the C IO
-/// interface to be more useful in a C++ context. For example the file is
-/// automatically closed in the destructor and if the file cannot be opened
-/// then an exception is thrown instead of returning a null pointer.
-class CFile {
-public:
-  struct NoThrowTag {};
-
-  /// Sets the handle to null if the file cannot be opened - does not
-  /// throw an exception. The purpose of the NoTrowTag parameter is only
-  /// to indicate that no exception should be thrown on error.
-  CFile(const std::string& fileName, const char* mode, NoThrowTag);
-
-  /// Opens the file and throws an exception if the file cannot be opened.
-  CFile(const std::string& fileName, const char* mode);
-
-  ~CFile();
-
-  bool hasFile() const {return mFile != 0;}
-
-  FILE* handle() {return mFile;}
-  void close();
-
-private:
-  FILE* mFile;
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_C_FILE_GUARD
+#define MATHICGB_C_FILE_GUARD
+
+#include <string>
+#include <cstdio>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// RAII handle for a C FILE*.
+///
+/// The purpose of using the C IO interface instead of iostreams is that the
+/// former is faster to a ridiculous degree. This class wraps the C IO
+/// interface to be more useful in a C++ context. For example the file is
+/// automatically closed in the destructor and if the file cannot be opened
+/// then an exception is thrown instead of returning a null pointer.
+class CFile {
+public:
+  struct NoThrowTag {};
+
+  /// Sets the handle to null if the file cannot be opened - does not
+  /// throw an exception. The purpose of the NoTrowTag parameter is only
+  /// to indicate that no exception should be thrown on error.
+  CFile(const ::std::string& fileName, const char* mode, NoThrowTag);
+
+  /// Opens the file and throws an exception if the file cannot be opened.
+  CFile(const ::std::string& fileName, const char* mode);
+
+  ~CFile();
+
+  bool hasFile() const {return mFile != 0;}
+
+  FILE* handle() {return mFile;}
+  void close();
+
+private:
+  FILE* mFile;
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/ChainedHashTable.cpp b/src/mathicgb/ChainedHashTable.cpp
old mode 100644
new mode 100755
index a68487a..97191be
--- a/src/mathicgb/ChainedHashTable.cpp
+++ b/src/mathicgb/ChainedHashTable.cpp
@@ -1,11 +1,10 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "ChainedHashTable.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 template class ChainedHashTable<HashControlExample>;
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/ChainedHashTable.hpp b/src/mathicgb/ChainedHashTable.hpp
old mode 100644
new mode 100755
index f6e3cef..b2a1c42
--- a/src/mathicgb/ChainedHashTable.hpp
+++ b/src/mathicgb/ChainedHashTable.hpp
@@ -1,14 +1,14 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _chainedHashTable_h_
-#define _chainedHashTable_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_CHAINED_HASH_TABLE_GUARD
+#define MATHICGB_CHAINED_HASH_TABLE_GUARD
 
 #include <vector>
 #include <iostream>
-
+#include <ostream>
 #include <memtailor.h>
 
-class ostream;
+MATHICGB_NAMESPACE_BEGIN
 
 // One template parameter, with the following:
 //   types:
@@ -281,10 +281,5 @@ void ChainedHashTable<HashControl>::dump(int level) const
     }
 }
 
-
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/ClassicGBAlg.cpp b/src/mathicgb/ClassicGBAlg.cpp
index 5603cd7..f4447f3 100755
--- a/src/mathicgb/ClassicGBAlg.cpp
+++ b/src/mathicgb/ClassicGBAlg.cpp
@@ -1,15 +1,20 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "ClassicGBAlg.hpp"
-#include "Basis.hpp"
 
+#include "Basis.hpp"
 #include "LogDomain.hpp"
 #include <iostream>
 
 MATHICGB_DEFINE_LOG_DOMAIN(
   SPairDegree,
-  "Displays the degree of the S-pairs being considered in Buchberger's algorithm."
+  "Displays the degree of the S-pairs being considered in "
+    "Buchberger's algorithm."
 );
 
+MATHICGB_NAMESPACE_BEGIN
+
 ClassicGBAlg::ClassicGBAlg(
   const Basis& basis,
   Reducer& reducer,
@@ -545,7 +550,4 @@ void ClassicGBAlg::printMemoryUse(std::ostream& out) const
   out << "*** Memory use by component ***\n" << pr << std::flush;
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/ClassicGBAlg.hpp b/src/mathicgb/ClassicGBAlg.hpp
index 7c9839d..f98af63 100755
--- a/src/mathicgb/ClassicGBAlg.hpp
+++ b/src/mathicgb/ClassicGBAlg.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_CLASSIC_GB_ALG_GUARD
 #define MATHICGB_CLASSIC_GB_ALG_GUARD
 
@@ -9,6 +11,8 @@
 #include <ostream>
 #include <vector>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class Basis;
 
 /// Calculates a classic Grobner basis using Buchberger's algorithm.
@@ -99,4 +103,5 @@ private:
   unsigned long long mSPolyReductionCount;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/DivLookup.hpp b/src/mathicgb/DivLookup.hpp
index ae55b12..806ac79 100755
--- a/src/mathicgb/DivLookup.hpp
+++ b/src/mathicgb/DivLookup.hpp
@@ -1,13 +1,16 @@
-#ifndef __div_lookup_guard_
-#define __div_lookup_guard_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_DIV_LOOKUP_GUARD
+#define MATHICGB_DIV_LOOKUP_GUARD
 
+#include "SigPolyBasis.hpp"
+#include "DivisorLookup.hpp"
+#include "PolyRing.hpp"
 #include <string>
 #include <vector>
 #include <iostream>
 
-#include "SigPolyBasis.hpp"
-#include "DivisorLookup.hpp"
-#include "PolyRing.hpp"
+MATHICGB_NAMESPACE_BEGIN
 
 /** Configuration class for interface to KDTree, DivList */
 /* As such, it has entries that both will expect */
@@ -602,9 +605,5 @@ size_t DivLookup<C>::getMemoryUse() const
   return 4 * sizeof(void *) * _finder.size();  // NOT CORRECT!!
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/DivisorLookup.cpp b/src/mathicgb/DivisorLookup.cpp
index 2d280c3..04102dd 100755
--- a/src/mathicgb/DivisorLookup.cpp
+++ b/src/mathicgb/DivisorLookup.cpp
@@ -1,11 +1,13 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "DivisorLookup.hpp"
 
-#include <mathic.h>
 #include "SigPolyBasis.hpp"
 #include "DivLookup.hpp"
+#include <mathic.h>
+
+MATHICGB_NAMESPACE_BEGIN
 
 namespace {
   struct DefaultParams {
@@ -123,7 +125,4 @@ void DivisorLookup::displayDivisorLookupTypes(std::ostream &o)
   o << "  4   kdtree" << std::endl;
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/DivisorLookup.hpp b/src/mathicgb/DivisorLookup.hpp
index 4ac6997..009de78 100755
--- a/src/mathicgb/DivisorLookup.hpp
+++ b/src/mathicgb/DivisorLookup.hpp
@@ -1,11 +1,13 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _divisor_lookup_h_
-#define _divisor_lookup_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_DIVISOR_LOOKUP_GUARD
+#define MATHICGB_DIVISOR_LOOKUP_GUARD
 
 #include "PolyRing.hpp"
 #include <vector>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class PolyBasis;
 class SigPolyBasis;
 
@@ -38,27 +40,28 @@ public:
   // but the outcome must be deterministic.
   virtual size_t classicReducer(const_monomial mon) const = 0;
 
-  virtual std::string getName() const = 0;
+  virtual ::std::string getName() const = 0;
 
   virtual size_t getMemoryUse() const = 0;
 
   virtual size_t highBaseDivisor(size_t newGenerator) const = 0;
   virtual void lowBaseDivisors(
-    std::vector<size_t>& divisors,
+    ::std::vector<size_t>& divisors,
     size_t maxDivisors,
     size_t newGenerator) const = 0;
   virtual size_t minimalLeadInSig(const_monomial sig) const = 0;
 
   virtual int type() const = 0;
 
-  static void displayDivisorLookupTypes(std::ostream &o);
+  static void displayDivisorLookupTypes(::std::ostream &o);
 
   class Factory {
   public:
-    virtual std::unique_ptr<DivisorLookup> create
+    virtual ::std::unique_ptr<DivisorLookup> create
       (bool preferSparseReducers, bool allowRemovals) const = 0;
   };
-  static std::unique_ptr<Factory> makeFactory(const PolyRing& ring, int type);
+  static ::std::unique_ptr<Factory> makeFactory
+    (const PolyRing& ring, int type);
   // choices for type: 1: divlist, 2:kdtree.
 
   class EntryOutput {
@@ -88,9 +91,5 @@ public:
   virtual size_t size() const = 0;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index a23b43e..c5bf37f 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "F4MatrixBuilder.hpp"
 
@@ -9,8 +11,10 @@ MATHICGB_DEFINE_LOG_DOMAIN(
   "Displays statistics about F4 matrix construction."
 );
 
+MATHICGB_NAMESPACE_BEGIN
+
 MATHICGB_NO_INLINE
-std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
 F4MatrixBuilder::findOrCreateColumn(
   const const_monomial monoA,
   const const_monomial monoB,
@@ -20,12 +24,12 @@ F4MatrixBuilder::findOrCreateColumn(
   MATHICGB_ASSERT(!monoB.isNull());
   const auto col = ColReader(mMap).findProduct(monoA, monoB);
   if (col.first != 0)
-    return std::make_pair(*col.first, col.second);
+    return ::std::make_pair(*col.first, col.second);
   return createColumn(monoA, monoB, feeder);
 }
 
 MATHICGB_INLINE
-std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
 F4MatrixBuilder::findOrCreateColumn(
   const const_monomial monoA,
   const const_monomial monoB,
@@ -37,7 +41,7 @@ F4MatrixBuilder::findOrCreateColumn(
   const auto col = colMap.findProduct(monoA, monoB);
   if (col.first == 0)
     return findOrCreateColumn(monoA, monoB, feeder);
-  return std::make_pair(*col.first, col.second);
+  return ::std::make_pair(*col.first, col.second);
 }
 
 MATHICGB_NO_INLINE
@@ -66,7 +70,7 @@ F4MatrixBuilder::F4MatrixBuilder(
 {
   // This assert to be _NO_ASSUME since otherwise the compiler will assume that
   // the error checking branch here cannot be taken and optimize it away.
-  const Scalar maxScalar = std::numeric_limits<Scalar>::max();
+  const Scalar maxScalar = ::std::numeric_limits<Scalar>::max();
   MATHICGB_ASSERT_NO_ASSUME(ring().charac() <= maxScalar);
   if (ring().charac() > maxScalar)
     mathic::reportInternalError("F4MatrixBuilder: too large characteristic.");
@@ -143,7 +147,7 @@ void F4MatrixBuilder::buildMatrixAndClear(QuadMatrix& matrix) {
       data.tmp1 = ring().allocMonomial();
       data.tmp2 = ring().allocMonomial();
     }
-    return std::move(data);
+    return ::std::move(data);
   });
 
   mgb::tbb::parallel_do(mTodo.begin(), mTodo.end(),
@@ -226,7 +230,7 @@ void F4MatrixBuilder::buildMatrixAndClear(QuadMatrix& matrix) {
   mMap.clearNonConcurrent();
 }
 
-std::pair<F4MatrixBuilder::LeftRightColIndex, ConstMonomial>
+::std::pair<F4MatrixBuilder::LeftRightColIndex, ConstMonomial>
 F4MatrixBuilder::createColumn(
   const const_monomial monoA,
   const const_monomial monoB,
@@ -240,7 +244,7 @@ F4MatrixBuilder::createColumn(
   {
     const auto found(ColReader(mMap).findProduct(monoA, monoB));
     if (found.first != 0)
-      return std::make_pair(*found.first, found.second);
+      return ::std::make_pair(*found.first, found.second);
   }
 
   // The column really does not exist, so we need to create it
@@ -254,10 +258,10 @@ F4MatrixBuilder::createColumn(
 
   // Create the new left or right column
   auto& colCount = insertLeft ? mLeftColCount : mRightColCount;
-  if (colCount == std::numeric_limits<ColIndex>::max())
-    throw std::overflow_error("Too many columns in QuadMatrix");
+  if (colCount == ::std::numeric_limits<ColIndex>::max())
+    throw ::std::overflow_error("Too many columns in QuadMatrix");
   const auto inserted = mMap.insert
-    (std::make_pair(mTmp, LeftRightColIndex(colCount, insertLeft)));
+    (::std::make_pair(mTmp, LeftRightColIndex(colCount, insertLeft)));
   ++colCount;
   MATHICGB_ASSERT(inserted.second);
   MATHICGB_ASSERT(inserted.first.first != 0);
@@ -271,7 +275,7 @@ F4MatrixBuilder::createColumn(
     feeder.add(task);
   }
 
-  return std::make_pair(*inserted.first.first, inserted.first.second);
+  return ::std::make_pair(*inserted.first.first, inserted.first.second);
 }
 
 void F4MatrixBuilder::appendRowBottom(
@@ -303,7 +307,7 @@ updateReader:
     MATHICGB_ASSERT(origScalar != 0);
     const auto maybeNegated =
       negate ? ring().coefficientNegateNonZero(origScalar) : origScalar;
-	MATHICGB_ASSERT(maybeNegated < std::numeric_limits<Scalar>::max());
+	MATHICGB_ASSERT(maybeNegated < ::std::numeric_limits<Scalar>::max());
     builder.appendEntryBottom(*col.first, static_cast<Scalar>(maybeNegated));
   }
   builder.rowDoneBottomLeftAndRight();
@@ -321,11 +325,11 @@ void F4MatrixBuilder::appendRowTop(
 
   auto it = poly.begin();
   const auto end = poly.end();
-  if ((std::distance(it, end) % 2) == 1) {
+  if ((::std::distance(it, end) % 2) == 1) {
     ColReader reader(mMap);
     const auto col = findOrCreateColumn
       (it.getMonomial(), multiple, reader, feeder);
-	MATHICGB_ASSERT(it.getCoefficient() < std::numeric_limits<Scalar>::max());
+	MATHICGB_ASSERT(it.getCoefficient() < ::std::numeric_limits<Scalar>::max());
     MATHICGB_ASSERT(it.getCoefficient());
     builder.appendEntryTop
       (col.first, static_cast<Scalar>(it.getCoefficient()));
@@ -333,16 +337,16 @@ void F4MatrixBuilder::appendRowTop(
   }
 updateReader:
   ColReader colMap(mMap);
-  MATHICGB_ASSERT((std::distance(it, end) % 2) == 0);
+  MATHICGB_ASSERT((::std::distance(it, end) % 2) == 0);
   while (it != end) {
-	MATHICGB_ASSERT(it.getCoefficient() < std::numeric_limits<Scalar>::max());
+	MATHICGB_ASSERT(it.getCoefficient() < ::std::numeric_limits<Scalar>::max());
     MATHICGB_ASSERT(it.getCoefficient() != 0);
     const auto scalar1 = static_cast<Scalar>(it.getCoefficient());
     const const_monomial mono1 = it.getMonomial();
 
     auto it2 = it;
     ++it2;
-	MATHICGB_ASSERT(it2.getCoefficient() < std::numeric_limits<Scalar>::max());
+	MATHICGB_ASSERT(it2.getCoefficient() < ::std::numeric_limits<Scalar>::max());
     MATHICGB_ASSERT(it2.getCoefficient() != 0);
     const auto scalar2 = static_cast<Scalar>(it2.getCoefficient());
     const const_monomial mono2 = it2.getMonomial();
@@ -420,8 +424,10 @@ void F4MatrixBuilder::appendRowBottom(
       col = colB.first;
       ++itB;
     }
-    MATHICGB_ASSERT(coeff < std::numeric_limits<Scalar>::max());
+    MATHICGB_ASSERT(coeff < ::std::numeric_limits<Scalar>::max());
     if (coeff != 0)
       builder.appendEntryBottom(col, static_cast<Scalar>(coeff));
   }
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/F4MatrixBuilder.hpp b/src/mathicgb/F4MatrixBuilder.hpp
index 9e3f267..91a53e6 100755
--- a/src/mathicgb/F4MatrixBuilder.hpp
+++ b/src/mathicgb/F4MatrixBuilder.hpp
@@ -1,157 +1,163 @@
-#ifndef F4_MATRIX_BUILDER_GUARD
-#define F4_MATRIX_BUILDER_GUARD
-
-#include "QuadMatrixBuilder.hpp"
-#include "Poly.hpp"
-#include "PolyRing.hpp"
-#include "PolyBasis.hpp"
-#include "QuadMatrix.hpp"
-#include "mtbb.hpp"
-#include <vector>
-
-/** Class for constructing an F4 matrix. This class is reponsible for
-  figuring out what matrix to build and then it uses QuadMatrixBuilder
-  to create that matrix.
-
-  @todo: this class does not offer exception guarantees. It's just not
-  very workable without an RAII monomial handle, so add one of those
-  before fixing this. */
-class F4MatrixBuilder {
-private:
-  typedef QuadMatrixBuilder::ColIndex ColIndex;
-  typedef QuadMatrixBuilder::LeftRightColIndex LeftRightColIndex;
-  typedef QuadMatrixBuilder::Scalar Scalar;
-  typedef QuadMatrixBuilder::Map Map;
-  typedef QuadMatrixBuilder::MonomialsType Monomials;
-
-public:
-  /// memoryQuantum is how much to increase the memory size by each time the
-  /// current amount of memory is exhausted. A value of 0 indicates to start
-  /// small and double the quantum at each exhaustion.
-  F4MatrixBuilder(const PolyBasis& basis, size_t memoryQuantum = 0);
-
-  /** Schedules a row representing the S-polynomial between polyA and
-    polyB to be added to the matrix. No ownership is taken, but polyA
-    and polyB must remain valid until the matrix is constructed.
-
-    Currently, the two monomials must be monic, though this is just
-    because they always happen to be monic so there was no reason to
-    support the non-monic case. */
-  void addSPolynomialToMatrix(const Poly& polyA, const Poly& polyB);
-
-  /** Schedules a row representing multiple*poly to be added to the
-    matrix. No ownership is taken, but poly must remain valid until
-    the matrix is constructed. multiple is copied so it need not
-    remain valid. */
-  void addPolynomialToMatrix(const_monomial multiple, const Poly& poly);
-
-  /// as the overload with a multiple, just letting multiple be the
-  /// identity.
-  void addPolynomialToMatrix(const Poly& poly);
-
-  /** Builds an F4 matrix to the specifications given. Also clears the
-    information in this object.
-
-    The right columns are ordered by decreasing monomial of each
-    column according to the order from the basis. The left columns are
-    ordered in some way so that the first entry in each top row (the
-    pivot) has a lower index than any other entries in that row.
-
-    The matrix contains a reducer/pivot for every monomial that can be
-    reduced by the basis and that is present in the matrix. There is
-    no guarantee that the bottom part of the matrix contains rows that
-    exactly correspond to the polynomials that have been scheduled to
-    be added to the matrix. It is only guaranteed that the whole matrix has
-    the same row-space as though that had been the case. */
-  void buildMatrixAndClear(QuadMatrix& matrix);
-
-  const PolyRing& ring() const {return mBuilder.ring();}
-
-private:
-  typedef const MonomialMap<LeftRightColIndex>::Reader ColReader;
-
-  /// Represents the task of adding a row to the matrix. If sPairPoly is null
-  /// then the row to add is multiply * poly. Otherwise, the row to add is
-  ///   multiply * poly - sPairMultiply * sPairPoly
-  /// where sPairMultiply makes the lead terms cancel.
-  struct RowTask {
-    bool addToTop; // add the row to the bottom if false
-    monomial desiredLead; // multiply monomial onto poly to get this lead
-    const Poly* poly;
-    const Poly* sPairPoly;
-    monomial sPairMultiply;
-  };
-  typedef ::mgb::tbb::parallel_do_feeder<RowTask> TaskFeeder;
-
-  /// Creates a column with monomial label x and schedules a new row to
-  /// reduce that column if possible. Here x is monoA if monoB is
-  /// null and otherwise x is the product of monoA and monoB.
-  MATHICGB_NO_INLINE
-  std::pair<LeftRightColIndex, ConstMonomial>
-  createColumn(
-    const_monomial monoA,
-    const_monomial monoB,
-    TaskFeeder& feeder
-  );
-
-  void appendRowTop(
-    const_monomial multiple,
-    const Poly& poly,
-    QuadMatrixBuilder& builder,
-    TaskFeeder& feeder
-  );
-  void appendRowBottom(
-    const Poly* poly,
-    monomial multiply,
-    const Poly* sPairPoly,
-    monomial sPairMultiply,
-    QuadMatrixBuilder& builder,
-    TaskFeeder& feeder
-  );
-  void appendRowBottom(
-    const_monomial multiple,
-    bool negate,
-    Poly::const_iterator begin,
-    Poly::const_iterator end,
-    QuadMatrixBuilder& builder,
-    TaskFeeder& feeder
-  );
-
-  MATHICGB_NO_INLINE
-  std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
-  findOrCreateColumn(
-    const_monomial monoA,
-    const_monomial monoB,
-    TaskFeeder& feeder
-  );
-  
-  MATHICGB_INLINE
-  std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
-  findOrCreateColumn(
-    const_monomial monoA,
-    const_monomial monoB,
-    const ColReader& colMap,
-    TaskFeeder& feeder
-  );
-
-  MATHICGB_NO_INLINE
-  void createTwoColumns(
-    const const_monomial monoA1,
-    const const_monomial monoA2,
-    const const_monomial monoB,
-    TaskFeeder& feeder
-  );
-
-  mgb::tbb::mutex mCreateColumnLock;
-  ColIndex mLeftColCount;
-  ColIndex mRightColCount;
-  monomial mTmp;
-  const PolyBasis& mBasis;
-  Monomials mMonomialsLeft;
-  Monomials mMonomialsRight;
-  QuadMatrixBuilder mBuilder;
-  Map mMap;
-  std::vector<RowTask> mTodo;
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_F4_MATRIX_BUILDER_GUARD
+#define MATHICGB_F4_MATRIX_BUILDER_GUARD
+
+#include "QuadMatrixBuilder.hpp"
+#include "Poly.hpp"
+#include "PolyRing.hpp"
+#include "PolyBasis.hpp"
+#include "QuadMatrix.hpp"
+#include "mtbb.hpp"
+#include <vector>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/** Class for constructing an F4 matrix. This class is reponsible for
+  figuring out what matrix to build and then it uses QuadMatrixBuilder
+  to create that matrix.
+
+  @todo: this class does not offer exception guarantees. It's just not
+  very workable without an RAII monomial handle, so add one of those
+  before fixing this. */
+class F4MatrixBuilder {
+private:
+  typedef QuadMatrixBuilder::ColIndex ColIndex;
+  typedef QuadMatrixBuilder::LeftRightColIndex LeftRightColIndex;
+  typedef QuadMatrixBuilder::Scalar Scalar;
+  typedef QuadMatrixBuilder::Map Map;
+  typedef QuadMatrixBuilder::MonomialsType Monomials;
+
+public:
+  /// memoryQuantum is how much to increase the memory size by each time the
+  /// current amount of memory is exhausted. A value of 0 indicates to start
+  /// small and double the quantum at each exhaustion.
+  F4MatrixBuilder(const PolyBasis& basis, size_t memoryQuantum = 0);
+
+  /** Schedules a row representing the S-polynomial between polyA and
+    polyB to be added to the matrix. No ownership is taken, but polyA
+    and polyB must remain valid until the matrix is constructed.
+
+    Currently, the two monomials must be monic, though this is just
+    because they always happen to be monic so there was no reason to
+    support the non-monic case. */
+  void addSPolynomialToMatrix(const Poly& polyA, const Poly& polyB);
+
+  /** Schedules a row representing multiple*poly to be added to the
+    matrix. No ownership is taken, but poly must remain valid until
+    the matrix is constructed. multiple is copied so it need not
+    remain valid. */
+  void addPolynomialToMatrix(const_monomial multiple, const Poly& poly);
+
+  /// as the overload with a multiple, just letting multiple be the
+  /// identity.
+  void addPolynomialToMatrix(const Poly& poly);
+
+  /** Builds an F4 matrix to the specifications given. Also clears the
+    information in this object.
+
+    The right columns are ordered by decreasing monomial of each
+    column according to the order from the basis. The left columns are
+    ordered in some way so that the first entry in each top row (the
+    pivot) has a lower index than any other entries in that row.
+
+    The matrix contains a reducer/pivot for every monomial that can be
+    reduced by the basis and that is present in the matrix. There is
+    no guarantee that the bottom part of the matrix contains rows that
+    exactly correspond to the polynomials that have been scheduled to
+    be added to the matrix. It is only guaranteed that the whole matrix has
+    the same row-space as though that had been the case. */
+  void buildMatrixAndClear(QuadMatrix& matrix);
+
+  const PolyRing& ring() const {return mBuilder.ring();}
+
+private:
+  typedef const MonomialMap<LeftRightColIndex>::Reader ColReader;
+
+  /// Represents the task of adding a row to the matrix. If sPairPoly is null
+  /// then the row to add is multiply * poly. Otherwise, the row to add is
+  ///   multiply * poly - sPairMultiply * sPairPoly
+  /// where sPairMultiply makes the lead terms cancel.
+  struct RowTask {
+    bool addToTop; // add the row to the bottom if false
+    monomial desiredLead; // multiply monomial onto poly to get this lead
+    const Poly* poly;
+    const Poly* sPairPoly;
+    monomial sPairMultiply;
+  };
+  typedef ::mgb::tbb::parallel_do_feeder<RowTask> TaskFeeder;
+
+  /// Creates a column with monomial label x and schedules a new row to
+  /// reduce that column if possible. Here x is monoA if monoB is
+  /// null and otherwise x is the product of monoA and monoB.
+  MATHICGB_NO_INLINE
+  ::std::pair<LeftRightColIndex, ConstMonomial>
+  createColumn(
+    const_monomial monoA,
+    const_monomial monoB,
+    TaskFeeder& feeder
+  );
+
+  void appendRowTop(
+    const_monomial multiple,
+    const Poly& poly,
+    QuadMatrixBuilder& builder,
+    TaskFeeder& feeder
+  );
+  void appendRowBottom(
+    const Poly* poly,
+    monomial multiply,
+    const Poly* sPairPoly,
+    monomial sPairMultiply,
+    QuadMatrixBuilder& builder,
+    TaskFeeder& feeder
+  );
+  void appendRowBottom(
+    const_monomial multiple,
+    bool negate,
+    Poly::const_iterator begin,
+    Poly::const_iterator end,
+    QuadMatrixBuilder& builder,
+    TaskFeeder& feeder
+  );
+
+  MATHICGB_NO_INLINE
+  ::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+  findOrCreateColumn(
+    const_monomial monoA,
+    const_monomial monoB,
+    TaskFeeder& feeder
+  );
+  
+  MATHICGB_INLINE
+  ::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+  findOrCreateColumn(
+    const_monomial monoA,
+    const_monomial monoB,
+    const ColReader& colMap,
+    TaskFeeder& feeder
+  );
+
+  MATHICGB_NO_INLINE
+  void createTwoColumns(
+    const const_monomial monoA1,
+    const const_monomial monoA2,
+    const const_monomial monoB,
+    TaskFeeder& feeder
+  );
+
+  mgb::tbb::mutex mCreateColumnLock;
+  ColIndex mLeftColCount;
+  ColIndex mRightColCount;
+  monomial mTmp;
+  const PolyBasis& mBasis;
+  Monomials mMonomialsLeft;
+  Monomials mMonomialsRight;
+  QuadMatrixBuilder mBuilder;
+  Map mMap;
+  ::std::vector<RowTask> mTodo;
+};
+
+MATHICGB_NAMESPACE_END
+
+#endif
diff --git a/src/mathicgb/F4MatrixBuilder2.cpp b/src/mathicgb/F4MatrixBuilder2.cpp
index 484332a..3fc82d8 100755
--- a/src/mathicgb/F4MatrixBuilder2.cpp
+++ b/src/mathicgb/F4MatrixBuilder2.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "F4MatrixBuilder2.hpp"
 
@@ -14,8 +16,10 @@ MATHICGB_DEFINE_LOG_DOMAIN(
   "Displays row and column count for each F4 matrix construction."
 );
 
+MATHICGB_NAMESPACE_BEGIN
+
 MATHICGB_NO_INLINE
-std::pair<F4MatrixBuilder2::ColIndex, ConstMonomial>
+::std::pair<F4MatrixBuilder2::ColIndex, ConstMonomial>
 F4MatrixBuilder2::findOrCreateColumn(
   const const_monomial monoA,
   const const_monomial monoB,
@@ -25,12 +29,12 @@ F4MatrixBuilder2::findOrCreateColumn(
   MATHICGB_ASSERT(!monoB.isNull());
   const auto col = ColReader(mMap).findProduct(monoA, monoB);
   if (col.first != 0)
-    return std::make_pair(*col.first, col.second);
+    return ::std::make_pair(*col.first, col.second);
   return createColumn(monoA, monoB, feeder);
 }
 
 MATHICGB_INLINE
-std::pair<F4MatrixBuilder2::ColIndex, ConstMonomial>
+::std::pair<F4MatrixBuilder2::ColIndex, ConstMonomial>
 F4MatrixBuilder2::findOrCreateColumn(
   const const_monomial monoA,
   const const_monomial monoB,
@@ -42,7 +46,7 @@ F4MatrixBuilder2::findOrCreateColumn(
   const auto col = colMap.findProduct(monoA, monoB);
   if (col.first == 0)
     return findOrCreateColumn(monoA, monoB, feeder);
-  return std::make_pair(*col.first, col.second);
+  return ::std::make_pair(*col.first, col.second);
 }
 
 MATHICGB_NO_INLINE
@@ -67,7 +71,7 @@ F4MatrixBuilder2::F4MatrixBuilder2(
 {
   // This assert has to be _NO_ASSUME since otherwise the compiler will assume
   // that the error checking branch here cannot be taken and optimize it away.
-  const Scalar maxScalar = std::numeric_limits<Scalar>::max();
+  const Scalar maxScalar = ::std::numeric_limits<Scalar>::max();
   MATHICGB_ASSERT_NO_ASSUME(ring().charac() <= maxScalar);
   if (ring().charac() > maxScalar)
     mathic::reportInternalError("F4MatrixBuilder2: too large characteristic.");
@@ -146,11 +150,11 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
     MATHICGB_ASSERT(ColReader(mMap).find(mTodo[i].desiredLead).first == 0);
 
     // Create column for the lead term that cancels in the S-pair
-    if (mIsColumnToLeft.size() >= std::numeric_limits<ColIndex>::max())
-      throw std::overflow_error("Too many columns in QuadMatrix");
+    if (mIsColumnToLeft.size() >= ::std::numeric_limits<ColIndex>::max())
+      throw ::std::overflow_error("Too many columns in QuadMatrix");
     const auto newIndex = static_cast<ColIndex>(mIsColumnToLeft.size());
     const auto inserted =
-      mMap.insert(std::make_pair(mTodo[i].desiredLead, newIndex));
+      mMap.insert(::std::make_pair(mTodo[i].desiredLead, newIndex));
     mIsColumnToLeft.push_back(true);
     const auto& mono = inserted.first.second;
 
@@ -204,7 +208,7 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
       data.tmp1 = ring().allocMonomial();
       data.tmp2 = ring().allocMonomial();
     }
-    return std::move(data);
+    return ::std::move(data);
   });
 
   // Construct the matrix as pre-blocks
@@ -256,15 +260,15 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
     (ring(), static_cast<ColIndex>(mMap.entryCount()));
   const auto end = threadData.end();
   for (auto it = threadData.begin(); it != end; ++it) {
-    projection.addProtoMatrix(std::move(it->block));
+    projection.addProtoMatrix(::std::move(it->block));
     ring().freeMonomial(it->tmp1);
     ring().freeMonomial(it->tmp2);
   }
 
   // Sort columns by monomial and tell the projection of the resulting order
   MonomialMap<ColIndex>::Reader reader(mMap);
-  typedef std::pair<ColIndex, ConstMonomial> IndexMono;
-  std::vector<IndexMono> columns(reader.begin(), reader.end());
+  typedef ::std::pair<ColIndex, ConstMonomial> IndexMono;
+  ::std::vector<IndexMono> columns(reader.begin(), reader.end());
   const auto cmp = [&](const IndexMono& a, const IndexMono b) {
     return ring().monomialLT(b.second, a.second);
   };
@@ -285,7 +289,7 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
     << " by "
     << mathic::ColumnPrinter::commafy(
          quadMatrix.computeLeftColCount() + quadMatrix.computeRightColCount())
-    << "]" << std::endl;
+    << "]" << ::std::endl;
 
 #ifdef MATHICGB_DEBUG
   for (size_t side = 0; side < 2; ++side) {
@@ -303,7 +307,7 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
 #endif
 }
 
-std::pair<F4MatrixBuilder2::ColIndex, ConstMonomial>
+::std::pair<F4MatrixBuilder2::ColIndex, ConstMonomial>
 F4MatrixBuilder2::createColumn(
   const const_monomial monoA,
   const const_monomial monoB,
@@ -317,7 +321,7 @@ F4MatrixBuilder2::createColumn(
   {
     const auto found(ColReader(mMap).findProduct(monoA, monoB));
     if (found.first != 0)
-      return std::make_pair(*found.first, found.second);
+      return ::std::make_pair(*found.first, found.second);
   }
 
   // The column really does not exist, so we need to create it
@@ -330,10 +334,10 @@ F4MatrixBuilder2::createColumn(
   const bool insertLeft = (reducerIndex != static_cast<size_t>(-1));
 
   // Create the new left or right column
-  if (mIsColumnToLeft.size() >= std::numeric_limits<ColIndex>::max())
-    throw std::overflow_error("Too many columns in QuadMatrix");
+  if (mIsColumnToLeft.size() >= ::std::numeric_limits<ColIndex>::max())
+    throw ::std::overflow_error("Too many columns in QuadMatrix");
   const auto newIndex = static_cast<ColIndex>(mIsColumnToLeft.size());
-  const auto inserted = mMap.insert(std::make_pair(mTmp, newIndex));
+  const auto inserted = mMap.insert(::std::make_pair(mTmp, newIndex));
   mIsColumnToLeft.push_back(insertLeft);
 
   // schedule new task if we found a reducer
@@ -344,7 +348,7 @@ F4MatrixBuilder2::createColumn(
     feeder.add(task);
   }
 
-  return std::make_pair(*inserted.first.first, inserted.first.second);
+  return ::std::make_pair(*inserted.first.first, inserted.first.second);
 }
 
 void F4MatrixBuilder2::appendRow(
@@ -357,8 +361,8 @@ void F4MatrixBuilder2::appendRow(
 
   const auto begin = poly.begin();
   const auto end = poly.end();
-  const auto count = static_cast<size_t>(std::distance(begin, end));
-  MATHICGB_ASSERT(count < std::numeric_limits<ColIndex>::max());
+  const auto count = static_cast<size_t>(::std::distance(begin, end));
+  MATHICGB_ASSERT(count < ::std::numeric_limits<ColIndex>::max());
   auto indices = block.makeRowWithTheseScalars(poly);
 
   auto it = begin;
@@ -366,7 +370,7 @@ void F4MatrixBuilder2::appendRow(
     ColReader reader(mMap);
     const auto col = findOrCreateColumn
       (it.getMonomial(), multiple, reader, feeder);
-	MATHICGB_ASSERT(it.getCoefficient() < std::numeric_limits<Scalar>::max());
+	MATHICGB_ASSERT(it.getCoefficient() < ::std::numeric_limits<Scalar>::max());
     MATHICGB_ASSERT(it.getCoefficient());
     //matrix.appendEntry(col.first, static_cast<Scalar>(it.getCoefficient()));
     *indices = col.first;
@@ -377,16 +381,16 @@ void F4MatrixBuilder2::appendRow(
   }
 updateReader:
   ColReader colMap(mMap);
-  MATHICGB_ASSERT((std::distance(it, end) % 2) == 0);
+  MATHICGB_ASSERT((::std::distance(it, end) % 2) == 0);
   while (it != end) {
-	MATHICGB_ASSERT(it.getCoefficient() < std::numeric_limits<Scalar>::max());
+	MATHICGB_ASSERT(it.getCoefficient() < ::std::numeric_limits<Scalar>::max());
     MATHICGB_ASSERT(it.getCoefficient() != 0);
     const auto scalar1 = static_cast<Scalar>(it.getCoefficient());
     const const_monomial mono1 = it.getMonomial();
 
     auto it2 = it;
     ++it2;
-	MATHICGB_ASSERT(it2.getCoefficient() < std::numeric_limits<Scalar>::max());
+	MATHICGB_ASSERT(it2.getCoefficient() < ::std::numeric_limits<Scalar>::max());
     MATHICGB_ASSERT(it2.getCoefficient() != 0);
     const auto scalar2 = static_cast<Scalar>(it2.getCoefficient());
     const const_monomial mono2 = it2.getMonomial();
@@ -441,7 +445,7 @@ void F4MatrixBuilder2::appendRowSPair(
 
   // @todo: handle overflow of termCount addition here
   MATHICGB_ASSERT(poly->termCount() + sPairPoly->termCount() - 2 <=
-    std::numeric_limits<ColIndex>::max());
+    ::std::numeric_limits<ColIndex>::max());
   const auto maxCols =
     static_cast<ColIndex>(poly->termCount() + sPairPoly->termCount() - 2);
   auto row = block.makeRow(maxCols);
@@ -470,7 +474,7 @@ void F4MatrixBuilder2::appendRowSPair(
       col = colB.first;
       ++itB;
     }
-    MATHICGB_ASSERT(coeff < std::numeric_limits<Scalar>::max());
+    MATHICGB_ASSERT(coeff < ::std::numeric_limits<Scalar>::max());
     if (coeff != 0) {
       //matrix.appendEntry(col, static_cast<Scalar>(coeff));
       *row.first++ = col;
@@ -499,3 +503,5 @@ void F4MatrixBuilder2::appendRowSPair(
     maxCols - static_cast<ColIndex>(row.first - indicesBegin);
   block.removeLastEntries(block.rowCount() - 1, toRemove);
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/F4MatrixBuilder2.hpp b/src/mathicgb/F4MatrixBuilder2.hpp
index f11328e..ab6bb1b 100755
--- a/src/mathicgb/F4MatrixBuilder2.hpp
+++ b/src/mathicgb/F4MatrixBuilder2.hpp
@@ -1,142 +1,147 @@
-#ifndef F4_MATRIX_BUILDER_2_GUARD
-#define F4_MATRIX_BUILDER_2_GUARD
-
-#include "SparseMatrix.hpp"
-#include "Poly.hpp"
-#include "PolyRing.hpp"
-#include "PolyBasis.hpp"
-#include "QuadMatrix.hpp"
-#include "MonomialMap.hpp"
-#include "F4ProtoMatrix.hpp"
-#include "mtbb.hpp"
-#include <vector>
-
-/** Class for constructing an F4 matrix.
-
-  @todo: this class does not offer exception guarantees. It's just not
-  very workable without an RAII monomial handle or a scope exit functionality,
-  so add one of those before fixing this. */
-class F4MatrixBuilder2 {
-private:
-  typedef SparseMatrix::ColIndex ColIndex;
-  typedef SparseMatrix::Scalar Scalar;
-  typedef MonomialMap<ColIndex> Map;
-  typedef SparseMatrix::RowIndex RowIndex;
-
-public:
-  /// memoryQuantum is how much to increase the memory size by each time the
-  /// current amount of memory is exhausted. A value of 0 indicates to start
-  /// small and double the quantum at each exhaustion.
-  F4MatrixBuilder2(const PolyBasis& basis, size_t memoryQuantum = 0);
-
-  /** Schedules a row representing the S-polynomial between polyA and
-    polyB to be added to the matrix. No ownership is taken, but polyA
-    and polyB must remain valid until the matrix is constructed.
-
-    Currently, the two monomials must be monic, though this is just
-    because they always happen to be monic so there was no reason to
-    support the non-monic case. */
-  void addSPolynomialToMatrix(const Poly& polyA, const Poly& polyB);
-
-  /** Schedules a row representing multiple*poly to be added to the
-    matrix. No ownership is taken, but poly must remain valid until
-    the matrix is constructed. multiple is copied so it need not
-    remain valid. */
-  void addPolynomialToMatrix(const_monomial multiple, const Poly& poly);
-
-  /// as the overload with a multiple, just letting multiple be the
-  /// identity.
-  void addPolynomialToMatrix(const Poly& poly);
-
-  /** Builds an F4 matrix to the specifications given. Also clears the
-    information in this object.
-
-    The right columns are ordered by decreasing monomial of each
-    column according to the order from the basis. The left columns are
-    ordered in some way so that the first entry in each top row (the
-    pivot) has a lower index than any other entries in that row.
-
-    The matrix contains a reducer/pivot for every monomial that can be
-    reduced by the basis and that is present in the matrix. There is
-    no guarantee that the bottom part of the matrix contains rows that
-    exactly correspond to the polynomials that have been scheduled to
-    be added to the matrix. It is only guaranteed that the whole matrix has
-    the same row-space as though that had been the case. */
-  void buildMatrixAndClear(QuadMatrix& matrix);
-
-  const PolyRing& ring() const {return mBasis.ring();}
-
-private:
-  typedef const Map::Reader ColReader;
-  typedef std::vector<monomial> Monomials;
-
-  /// Represents the task of adding a row to the matrix. If sPairPoly is null
-  /// then the row to add is multiply * poly. Otherwise, the row to add is
-  ///   multiply * poly - sPairMultiply * sPairPoly
-  /// where multiply and sPairMultiply are such that the leading terms become
-  /// desiredLead.
-  struct RowTask {
-    monomial desiredLead; // multiply monomial onto poly to get this lead
-    const Poly* poly;
-    const Poly* sPairPoly;
-  };
-  typedef mgb::tbb::parallel_do_feeder<RowTask> TaskFeeder;
-
-  /// Creates a column with monomial label x and schedules a new row to
-  /// reduce that column if possible. Here x is monoA if monoB is
-  /// null and otherwise x is the product of monoA and monoB.
-  MATHICGB_NO_INLINE
-  std::pair<ColIndex, ConstMonomial> createColumn(
-    const_monomial monoA,
-    const_monomial monoB,
-    TaskFeeder& feeder
-  );
-
-  void appendRow(
-    const_monomial multiple,
-    const Poly& poly,
-    F4ProtoMatrix& block,
-    TaskFeeder& feeder
-  );
-  void appendRowSPair(
-    const Poly* poly,
-    monomial multiply,
-    const Poly* sPairPoly,
-    monomial sPairMultiply,
-    F4ProtoMatrix& block,
-    TaskFeeder& feeder
-  );
-
-  MATHICGB_NO_INLINE
-  std::pair<ColIndex, ConstMonomial> findOrCreateColumn(
-    const_monomial monoA,
-    const_monomial monoB,
-    TaskFeeder& feeder
-  );
-  
-  MATHICGB_INLINE
-  std::pair<ColIndex, ConstMonomial> findOrCreateColumn(
-    const_monomial monoA,
-    const_monomial monoB,
-    const ColReader& colMap,
-    TaskFeeder& feeder
-  );
-
-  MATHICGB_NO_INLINE
-  void createTwoColumns(
-    const const_monomial monoA1,
-    const const_monomial monoA2,
-    const const_monomial monoB,
-    TaskFeeder& feeder
-  );
-
-  std::vector<char> mIsColumnToLeft;
-  const size_t mMemoryQuantum;
-  mgb::tbb::mutex mCreateColumnLock;
-  monomial mTmp;
-  const PolyBasis& mBasis;
-  Map mMap;
-  std::vector<RowTask> mTodo;
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_F4_MATRIX_BUILDER_2_GUARD
+#define MATHICGB_F4_MATRIX_BUILDER_2_GUARD
+
+#include "SparseMatrix.hpp"
+#include "Poly.hpp"
+#include "PolyRing.hpp"
+#include "PolyBasis.hpp"
+#include "QuadMatrix.hpp"
+#include "MonomialMap.hpp"
+#include "F4ProtoMatrix.hpp"
+#include "mtbb.hpp"
+#include <vector>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/** Class for constructing an F4 matrix.
+
+  @todo: this class does not offer exception guarantees. It's just not
+  very workable without an RAII monomial handle or a scope exit functionality,
+  so add one of those before fixing this. */
+class F4MatrixBuilder2 {
+private:
+  typedef SparseMatrix::ColIndex ColIndex;
+  typedef SparseMatrix::Scalar Scalar;
+  typedef MonomialMap<ColIndex> Map;
+  typedef SparseMatrix::RowIndex RowIndex;
+
+public:
+  /// memoryQuantum is how much to increase the memory size by each time the
+  /// current amount of memory is exhausted. A value of 0 indicates to start
+  /// small and double the quantum at each exhaustion.
+  F4MatrixBuilder2(const PolyBasis& basis, size_t memoryQuantum = 0);
+
+  /** Schedules a row representing the S-polynomial between polyA and
+    polyB to be added to the matrix. No ownership is taken, but polyA
+    and polyB must remain valid until the matrix is constructed.
+
+    Currently, the two monomials must be monic, though this is just
+    because they always happen to be monic so there was no reason to
+    support the non-monic case. */
+  void addSPolynomialToMatrix(const Poly& polyA, const Poly& polyB);
+
+  /** Schedules a row representing multiple*poly to be added to the
+    matrix. No ownership is taken, but poly must remain valid until
+    the matrix is constructed. multiple is copied so it need not
+    remain valid. */
+  void addPolynomialToMatrix(const_monomial multiple, const Poly& poly);
+
+  /// as the overload with a multiple, just letting multiple be the
+  /// identity.
+  void addPolynomialToMatrix(const Poly& poly);
+
+  /** Builds an F4 matrix to the specifications given. Also clears the
+    information in this object.
+
+    The right columns are ordered by decreasing monomial of each
+    column according to the order from the basis. The left columns are
+    ordered in some way so that the first entry in each top row (the
+    pivot) has a lower index than any other entries in that row.
+
+    The matrix contains a reducer/pivot for every monomial that can be
+    reduced by the basis and that is present in the matrix. There is
+    no guarantee that the bottom part of the matrix contains rows that
+    exactly correspond to the polynomials that have been scheduled to
+    be added to the matrix. It is only guaranteed that the whole matrix has
+    the same row-space as though that had been the case. */
+  void buildMatrixAndClear(QuadMatrix& matrix);
+
+  const PolyRing& ring() const {return mBasis.ring();}
+
+private:
+  typedef const Map::Reader ColReader;
+  typedef ::std::vector<monomial> Monomials;
+
+  /// Represents the task of adding a row to the matrix. If sPairPoly is null
+  /// then the row to add is multiply * poly. Otherwise, the row to add is
+  ///   multiply * poly - sPairMultiply * sPairPoly
+  /// where multiply and sPairMultiply are such that the leading terms become
+  /// desiredLead.
+  struct RowTask {
+    monomial desiredLead; // multiply monomial onto poly to get this lead
+    const Poly* poly;
+    const Poly* sPairPoly;
+  };
+  typedef mgb::tbb::parallel_do_feeder<RowTask> TaskFeeder;
+
+  /// Creates a column with monomial label x and schedules a new row to
+  /// reduce that column if possible. Here x is monoA if monoB is
+  /// null and otherwise x is the product of monoA and monoB.
+  MATHICGB_NO_INLINE
+  ::std::pair<ColIndex, ConstMonomial> createColumn(
+    const_monomial monoA,
+    const_monomial monoB,
+    TaskFeeder& feeder
+  );
+
+  void appendRow(
+    const_monomial multiple,
+    const Poly& poly,
+    F4ProtoMatrix& block,
+    TaskFeeder& feeder
+  );
+  void appendRowSPair(
+    const Poly* poly,
+    monomial multiply,
+    const Poly* sPairPoly,
+    monomial sPairMultiply,
+    F4ProtoMatrix& block,
+    TaskFeeder& feeder
+  );
+
+  MATHICGB_NO_INLINE
+  ::std::pair<ColIndex, ConstMonomial> findOrCreateColumn(
+    const_monomial monoA,
+    const_monomial monoB,
+    TaskFeeder& feeder
+  );
+  
+  MATHICGB_INLINE
+  ::std::pair<ColIndex, ConstMonomial> findOrCreateColumn(
+    const_monomial monoA,
+    const_monomial monoB,
+    const ColReader& colMap,
+    TaskFeeder& feeder
+  );
+
+  MATHICGB_NO_INLINE
+  void createTwoColumns(
+    const const_monomial monoA1,
+    const const_monomial monoA2,
+    const const_monomial monoB,
+    TaskFeeder& feeder
+  );
+
+  ::std::vector<char> mIsColumnToLeft;
+  const size_t mMemoryQuantum;
+  mgb::tbb::mutex mCreateColumnLock;
+  monomial mTmp;
+  const PolyBasis& mBasis;
+  Map mMap;
+  ::std::vector<RowTask> mTodo;
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/F4MatrixProjection.cpp b/src/mathicgb/F4MatrixProjection.cpp
index 80b22ab..0855170 100755
--- a/src/mathicgb/F4MatrixProjection.cpp
+++ b/src/mathicgb/F4MatrixProjection.cpp
@@ -1,8 +1,12 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "F4MatrixProjection.hpp"
 
 #include "ScopeExit.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 F4MatrixProjection::F4MatrixProjection(
   const PolyRing& ring,
   ColIndex colCount
@@ -43,27 +47,27 @@ struct RowData : F4ProtoMatrix::Row {
   RowData(const F4ProtoMatrix::Row& row): F4ProtoMatrix::Row(row) {}
 };
 
-typedef std::pair<RowData, SparseMatrix::Scalar> RowProjectFrom;
+typedef ::std::pair<RowData, SparseMatrix::Scalar> RowProjectFrom;
 
 
 template<class Row>
 class F4MatrixProjection::TopBottom {
 public:
-  typedef std::pair<Row, Scalar> RowMultiple;
-  typedef std::vector<RowMultiple> RowVector;
+  typedef ::std::pair<Row, Scalar> RowMultiple;
+  typedef ::std::vector<RowMultiple> RowVector;
 
   TopBottom(const size_t leftColCount, const PolyRing& ring):
     mModulus(static_cast<Scalar>(ring.charac())),
     mTopRows(leftColCount)
   {
-    MATHICGB_ASSERT(ring.charac() <= std::numeric_limits<Scalar>::max());
-    MATHICGB_ASSERT(leftColCount <= std::numeric_limits<ColIndex>::max());
+    MATHICGB_ASSERT(ring.charac() <= ::std::numeric_limits<Scalar>::max());
+    MATHICGB_ASSERT(leftColCount <= ::std::numeric_limits<ColIndex>::max());
   }
 
   void addRow(const Row& row, ColIndex leadIndex, Scalar leadScalar) {
     if (row.entryCount == 0)
       return; // Skip zero rows.
-    if (leadIndex == std::numeric_limits<ColIndex>::max()) {
+    if (leadIndex == ::std::numeric_limits<ColIndex>::max()) {
       // this row has no left entries, so it cannot be a top row.
       mBottomRows.push_back(RowMultiple(row, 1));
       return;
@@ -77,7 +81,7 @@ public:
       mBottomRows.push_back(RowMultiple(row, 1));
     } else {
       if (currentTop.entryCount != 0)
-        mBottomRows.push_back(std::make_pair(currentTop, 1));
+        mBottomRows.push_back(::std::make_pair(currentTop, 1));
       MATHICGB_ASSERT(leadScalar != 0);
       const auto inverse = leadScalar == 1 ? // 1 is a common case
         1 : modularInverse(leadScalar, mModulus);
@@ -91,8 +95,8 @@ public:
       MATHICGB_ASSERT(r.first.entryCount > 0);
       MATHICGB_ASSERT(r.second != 0);
     };
-    std::for_each(mTopRows.begin(), mTopRows.end(), check);
-    std::for_each(mBottomRows.begin(), mBottomRows.end(), check);
+    ::std::for_each(mTopRows.begin(), mTopRows.end(), check);
+    ::std::for_each(mBottomRows.begin(), mBottomRows.end(), check);
 #endif
     return true;
   }
@@ -116,7 +120,7 @@ public:
   typedef F4ProtoMatrix::Row Row;
 
   LeftRight(
-    const std::vector<ColProjectTo>& colProjectTo,
+    const ::std::vector<ColProjectTo>& colProjectTo,
     const PolyRing& ring,
     const size_t quantum
   ):
@@ -125,19 +129,19 @@ public:
     mLeft(quantum),
     mRight(quantum)
   {
-    MATHICGB_ASSERT(ring.charac() < std::numeric_limits<Scalar>::max());
+    MATHICGB_ASSERT(ring.charac() < ::std::numeric_limits<Scalar>::max());
     mLeft.clear();
     mRight.clear();
   }
 
   template<class Pair>
-  void appendRowsPermuted(const std::vector<Pair>& rows) {
+  void appendRowsPermuted(const ::std::vector<Pair>& rows) {
     const auto end = rows.end();
     for (auto it = rows.begin(); it != end; ++it)
       appendRow(it->first, it->second);
   }
 
-  void appendRows(const std::vector<F4ProtoMatrix*>& preBlocks) {
+  void appendRows(const ::std::vector<F4ProtoMatrix*>& preBlocks) {
     const auto end = preBlocks.end();
     for (auto it = preBlocks.begin(); it != end; ++it) {
       auto& block = **it;
@@ -194,7 +198,7 @@ public:
   }
 
   void appendEntry(const ColIndex projectMe, const ExternalScalar scalar) {
-    MATHICGB_ASSERT(scalar <= std::numeric_limits<Scalar>::max());
+    MATHICGB_ASSERT(scalar <= ::std::numeric_limits<Scalar>::max());
     appendEntry(projectMe, static_cast<Scalar>(scalar));
   }
 
@@ -207,11 +211,11 @@ public:
   const SparseMatrix& left() const {return mLeft;}
   const SparseMatrix& right() const {return mRight;}
 
-  SparseMatrix moveLeft() {return std::move(mLeft);}
-  SparseMatrix moveRight() {return std::move(mRight);}
+  SparseMatrix moveLeft() {return ::std::move(mLeft);}
+  SparseMatrix moveRight() {return ::std::move(mRight);}
 
 private:
-  const std::vector<ColProjectTo>& mColProjectTo;
+  const ::std::vector<ColProjectTo>& mColProjectTo;
   const Scalar mModulus;
 
   SparseMatrix mLeft;
@@ -251,7 +255,7 @@ QuadMatrix F4MatrixProjection::makeAndClearOneStep(const size_t quantum) {
         }
       }
       // Did not find any left entry.
-      tb.addRow(row, std::numeric_limits<ColIndex>::max(), 0);
+      tb.addRow(row, ::std::numeric_limits<ColIndex>::max(), 0);
 done:;
     }
   }
@@ -267,21 +271,21 @@ done:;
   // Move the data into place
   QuadMatrix qm;
   qm.ring = &ring();
-  qm.leftColumnMonomials = std::move(mLeftMonomials);
-  qm.rightColumnMonomials = std::move(mRightMonomials);
+  qm.leftColumnMonomials = ::std::move(mLeftMonomials);
+  qm.rightColumnMonomials = ::std::move(mRightMonomials);
 
   qm.topLeft = top.moveLeft();
   qm.topRight = top.moveRight();
   qm.bottomLeft = bottom.moveLeft();
   qm.bottomRight = bottom.moveRight();
 
-  return std::move(qm);
+  return ::std::move(qm);
 }
 
 namespace {
   // Helper function for F4MatrixProjection::makeAndClearTwoStep
   template<class TopBottom>
-  std::pair<SparseMatrix, SparseMatrix> projectRows(
+  ::std::pair<SparseMatrix, SparseMatrix> projectRows(
     const TopBottom& tb,
     size_t quantum,
     SparseMatrix&& in
@@ -309,7 +313,7 @@ namespace {
     }
 
     in.clear();
-    return std::make_pair(std::move(top), std::move(bottom));
+    return ::std::make_pair(::std::move(top), ::std::move(bottom));
   }
 }
 
@@ -334,7 +338,7 @@ QuadMatrix F4MatrixProjection::makeAndClearTwoStep(const size_t quantum) {
 
     const Row r = {row, entryCount};
     if (leftEntryCount == 0)
-      tb.addRow(r, std::numeric_limits<ColIndex>::max(), 0);
+      tb.addRow(r, ::std::numeric_limits<ColIndex>::max(), 0);
     else {
       const auto entry = lr.left().rowBegin(row);
       tb.addRow(r, entry.index(), entry.scalar());
@@ -347,11 +351,13 @@ QuadMatrix F4MatrixProjection::makeAndClearTwoStep(const size_t quantum) {
   auto right = projectRows(tb, quantum, lr.moveRight());
 
   qm.ring = &ring();
-  qm.topLeft = std::move(left.first);
-  qm.bottomLeft = std::move(left.second);
-  qm.topRight = std::move(right.first);
-  qm.bottomRight = std::move(right.second);
-  qm.leftColumnMonomials = std::move(mLeftMonomials);
-  qm.rightColumnMonomials = std::move(mRightMonomials);
-  return std::move(qm);
+  qm.topLeft = ::std::move(left.first);
+  qm.bottomLeft = ::std::move(left.second);
+  qm.topRight = ::std::move(right.first);
+  qm.bottomRight = ::std::move(right.second);
+  qm.leftColumnMonomials = ::std::move(mLeftMonomials);
+  qm.rightColumnMonomials = ::std::move(mRightMonomials);
+  return ::std::move(qm);
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/F4MatrixProjection.hpp b/src/mathicgb/F4MatrixProjection.hpp
old mode 100644
new mode 100755
index c34c75f..66c8ffc
--- a/src/mathicgb/F4MatrixProjection.hpp
+++ b/src/mathicgb/F4MatrixProjection.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_F4_MATRIX_PROJECTION_GUARD
 #define MATHICGB_F4_MATRIX_PROJECTION_GUARD
 
@@ -8,6 +10,8 @@
 #include "ScopeExit.hpp"
 #include <vector>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class F4MatrixProjection {
 public:
   typedef SparseMatrix::RowIndex RowIndex;
@@ -41,12 +45,14 @@ private:
     ColIndex index;
     bool isLeft;
   };
-  std::vector<ColProjectTo> mColProjectTo;
+  ::std::vector<ColProjectTo> mColProjectTo;
 
-  std::vector<F4ProtoMatrix*> mMatrices;
-  std::vector<monomial> mLeftMonomials;
-  std::vector<monomial> mRightMonomials;
+  ::std::vector<F4ProtoMatrix*> mMatrices;
+  ::std::vector<monomial> mLeftMonomials;
+  ::std::vector<monomial> mRightMonomials;
   const PolyRing& mRing;
 };
 
+MATHICGB_NAMESPACE_END
+
 #endif
diff --git a/src/mathicgb/F4MatrixReducer.cpp b/src/mathicgb/F4MatrixReducer.cpp
index 99b71d8..f556901 100755
--- a/src/mathicgb/F4MatrixReducer.cpp
+++ b/src/mathicgb/F4MatrixReducer.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "F4MatrixReducer.hpp"
 
@@ -6,7 +8,6 @@
 #include "PolyRing.hpp"
 #include "LogDomain.hpp"
 #include "mtbb.hpp"
-
 #include <algorithm>
 #include <vector>
 #include <stdexcept>
@@ -30,6 +31,8 @@ MATHICGB_DEFINE_LOG_DOMAIN(
   "Displays time to reduce the bottom right submatrix of each F4 matrix."
 );
 
+MATHICGB_NAMESPACE_BEGIN
+
 namespace {
   class DenseRow {
   public:
@@ -148,7 +151,7 @@ namespace {
       // method).
 
       auto it = begin;
-      if (std::distance(begin, end) % 2 == 1) {
+      if (::std::distance(begin, end) % 2 == 1) {
         // Replacing this by a goto into the middle of the following loop
         // (similar to Duff's device) made the code slower on MSVC 2012.
         multiplyAdd(it.scalar(), multiple, entries[it.index()]);
@@ -185,7 +188,7 @@ namespace {
     }
 
   private:
-    std::vector<ScalarProductSum> mEntries;
+    ::std::vector<ScalarProductSum> mEntries;
   };
 
   SparseMatrix reduce(
@@ -211,10 +214,10 @@ namespace {
     // Store column indexes instead of row indices as the matrix is square
     // anyway (so all indices fit) and we are going to store this as a column
     // index later on.
-    std::vector<SparseMatrix::ColIndex> rowThatReducesCol(pivotCount);
+    ::std::vector<SparseMatrix::ColIndex> rowThatReducesCol(pivotCount);
 #ifdef MATHICGB_DEBUG
     // fill in an invalid value that can be recognized by asserts to be invalid.
-    std::fill(rowThatReducesCol.begin(), rowThatReducesCol.end(), pivotCount);
+    ::std::fill(rowThatReducesCol.begin(), rowThatReducesCol.end(), pivotCount);
 #endif
     for (SparseMatrix::ColIndex pivot = 0; pivot < pivotCount; ++pivot) {
       MATHICGB_ASSERT(!reduceByLeft.emptyRow(pivot));
@@ -236,7 +239,7 @@ namespace {
 
     SparseMatrix tmp(qm.topRight.memoryQuantum());
 
-    std::vector<SparseMatrix::RowIndex> rowOrder(rowCount);
+    ::std::vector<SparseMatrix::RowIndex> rowOrder(rowCount);
 
     mgb::tbb::mutex lock;
     mgb::tbb::parallel_for(mgb::tbb::blocked_range<SparseMatrix::RowIndex>(0, rowCount, 2),
@@ -261,7 +264,7 @@ namespace {
               MATHICGB_ASSERT(row < pivotCount);
               MATHICGB_ASSERT(!reduceByLeft.emptyRow(row));
               MATHICGB_ASSERT(reduceByLeft.leadCol(row) == pivot);
-              MATHICGB_ASSERT(entry < std::numeric_limits<SparseMatrix::Scalar>::max());
+              MATHICGB_ASSERT(entry < ::std::numeric_limits<SparseMatrix::Scalar>::max());
               denseRow.addRowMultiple(
                 static_cast<SparseMatrix::Scalar>(entry),
                 ++reduceByLeft.rowBegin(row),
@@ -273,7 +276,7 @@ namespace {
         }
         mgb::tbb::mutex::scoped_lock lockGuard(lock);
         for (size_t pivot = 0; pivot < pivotCount; ++pivot) {
-		  MATHICGB_ASSERT(denseRow[pivot] < std::numeric_limits<SparseMatrix::Scalar>::max());
+		  MATHICGB_ASSERT(denseRow[pivot] < ::std::numeric_limits<SparseMatrix::Scalar>::max());
           if (denseRow[pivot] != 0)
             tmp.appendEntry(rowThatReducesCol[pivot], static_cast<SparseMatrix::Scalar>(denseRow[pivot]));
 	    }
@@ -313,7 +316,7 @@ namespace {
       if (!zero)
         reduced.rowDone();
     }});
-    return std::move(reduced);
+    return ::std::move(reduced);
   }
 
   SparseMatrix reduceToEchelonFormSparse(
@@ -326,7 +329,7 @@ namespace {
 
     // pivotRowOfCol[i] is the pivot in column i or noRow
     // if we have not identified such a pivot so far.
-    std::vector<SparseMatrix::RowIndex> pivotRowOfCol(colCount, noRow);
+    ::std::vector<SparseMatrix::RowIndex> pivotRowOfCol(colCount, noRow);
 
     DenseRow rowToReduce(colCount);
 
@@ -391,7 +394,7 @@ namespace {
       pivotRowOfCol[pivotCol] = reduced.rowCount();
       rowToReduce.appendTo(reduced);
     }
-    return std::move(reduced);
+    return ::std::move(reduced);
   }
 
   SparseMatrix reduceToEchelonForm(
@@ -402,7 +405,7 @@ namespace {
     const auto rowCount = toReduce.rowCount();
 
     // convert to dense representation 
-    std::vector<DenseRow> dense(rowCount);
+    ::std::vector<DenseRow> dense(rowCount);
     mgb::tbb::parallel_for(mgb::tbb::blocked_range<SparseMatrix::RowIndex>(0, rowCount),
       [&](const mgb::tbb::blocked_range<SparseMatrix::RowIndex>& range)
       {for (auto it = range.begin(); it != range.end(); ++it)
@@ -415,28 +418,28 @@ namespace {
     }});
 
     // invariant: all columns in row to the left of leadCols[row] are zero.
-    std::vector<SparseMatrix::ColIndex> leadCols(rowCount);
+    ::std::vector<SparseMatrix::ColIndex> leadCols(rowCount);
 
     // pivot rows get copied here before being used to reduce the matrix.
     SparseMatrix reduced(toReduce.memoryQuantum());
 
     // (col,row) in nextReducers, then use row as a pivot in column col
     // for the next iteration.
-    std::vector<std::pair<SparseMatrix::ColIndex, SparseMatrix::RowIndex> > nextReducers;
+    ::std::vector< ::std::pair<SparseMatrix::ColIndex, SparseMatrix::RowIndex> > nextReducers;
 
     // isPivotRow[row] is true if row is or has been used as a pivot.
-    std::vector<bool> isPivotRow(rowCount);
+    ::std::vector<bool> isPivotRow(rowCount);
 
     // columnHasPivot[col] is true if a pivot row for column col has
     // been chosen.
-    std::vector<bool> columnHasPivot(colCount);
+    ::std::vector<bool> columnHasPivot(colCount);
 
     bool firstIteration = true;
     while (firstIteration || reduced.rowCount() > 0) {
       firstIteration = false;
       size_t const reducerCount = reduced.rowCount();
 
-      //std::cout << "reducing " << reduced.rowCount() << " out of " << toReduce.rowCount() << std::endl;
+      //::std::cout << "reducing " << reduced.rowCount() << " out of " << toReduce.rowCount() << ::std::endl;
       mgb::tbb::mutex lock;
       mgb::tbb::parallel_for(mgb::tbb::blocked_range<SparseMatrix::RowIndex>(0, rowCount),
         [&](const mgb::tbb::blocked_range<SparseMatrix::RowIndex>& range)
@@ -478,17 +481,17 @@ namespace {
             if (!columnHasPivot[col]) {
               columnHasPivot[col] = true;
               isNewReducer = true;
-              nextReducers.push_back(std::make_pair(col, row));
+              nextReducers.push_back(::std::make_pair(col, row));
             }
           }
           if (isNewReducer)
             denseRow.makeUnitary(modulus, col);
         }
       }});
-      //std::cout << "done reducing that batch" << std::endl;
+      //::std::cout << "done reducing that batch" << ::std::endl;
 
       reduced.clear();
-      std::sort(nextReducers.begin(), nextReducers.end());
+      ::std::sort(nextReducers.begin(), nextReducers.end());
       for (size_t i = 0; i < nextReducers.size(); ++i) {
         size_t const row = nextReducers[i].second;
 
@@ -514,7 +517,7 @@ namespace {
     }});
 
 #ifdef MATHICGB_DEBUG
-    std::vector<char> sawPivot(colCount);
+    ::std::vector<char> sawPivot(colCount);
     for (SparseMatrix::RowIndex row = 0; row < rowCount; ++row) {
       if (dense[row].empty()) {
         MATHICGB_ASSERT(!isPivotRow[row]);
@@ -546,7 +549,7 @@ namespace {
     for (size_t row = 0; row < rowCount; ++row)
       if (!dense[row].empty())
         dense[row].appendTo(reduced);
-    return std::move(reduced);
+    return ::std::move(reduced);
   }
 }
 
@@ -581,7 +584,7 @@ private:
 };
 */
 void addRowMultipleInplace(
-  std::vector<std::vector<SparseMatrix::Scalar> >& matrix,
+  ::std::vector< ::std::vector<SparseMatrix::Scalar> >& matrix,
   const SparseMatrix::RowIndex addRow,
   const SparseMatrix::Scalar multiple,
   const SparseMatrix::RowIndex row,
@@ -603,7 +606,7 @@ void addRowMultipleInplace(
 }
 
 void makeRowUnitary(
-  std::vector<std::vector<SparseMatrix::Scalar>>& matrix,
+  ::std::vector< ::std::vector<SparseMatrix::Scalar>>& matrix,
   const SparseMatrix::RowIndex row,
   const SparseMatrix::ColIndex colCount,
   const SparseMatrix::ColIndex leadingCol,
@@ -624,7 +627,7 @@ void makeRowUnitary(
 
 // todo: make this take a parameter startAtCol 									::DONE
 SparseMatrix::ColIndex leadingColumn(
-  const std::vector<std::vector<SparseMatrix::Scalar>>& matrix,
+  const ::std::vector< ::std::vector<SparseMatrix::Scalar>>& matrix,
   const SparseMatrix::RowIndex row,
   const SparseMatrix::ColIndex colCount,
   SparseMatrix::ColIndex startAtCol 
@@ -639,7 +642,7 @@ SparseMatrix::ColIndex leadingColumn(
 }
 
 void rowReducedEchelonMatrix(
-  std::vector<std::vector<SparseMatrix::Scalar> >& matrix,
+  ::std::vector< ::std::vector<SparseMatrix::Scalar> >& matrix,
   const SparseMatrix::ColIndex colCount,
   const SparseMatrix::Scalar modulus
 ) {
@@ -648,7 +651,7 @@ void rowReducedEchelonMatrix(
     static_cast<SparseMatrix::RowIndex>(matrix.size());
   // pivotRowOfCol[i] is the pivot in column i or rowCount
   // if we have not identified such a pivot so far.
-  std::vector<SparseMatrix::RowIndex> pivotRowOfCol(colCount, rowCount);
+  ::std::vector<SparseMatrix::RowIndex> pivotRowOfCol(colCount, rowCount);
   
   // row reduce to row echelon form
   for(SparseMatrix::RowIndex row=0; row<rowCount;++row) { 
@@ -693,7 +696,7 @@ SparseMatrix reduceToEchelonFormShrawan(
   const auto colCount = toReduce.computeColCount();
 
   // Convert input matrix to dense format
-  std::vector<std::vector<SparseMatrix::Scalar>> matrix(rowCount);
+  ::std::vector< ::std::vector<SparseMatrix::Scalar>> matrix(rowCount);
   for (SparseMatrix::RowIndex row = 0; row < rowCount; ++row) {
     MATHICGB_ASSERT(!toReduce.emptyRow(row));
     matrix[row].resize(colCount);
@@ -721,7 +724,7 @@ SparseMatrix reduceToEchelonFormShrawan(
     if (!rowIsZero)
       reduced.rowDone();
   }
-  return std::move(reduced);
+  return ::std::move(reduced);
 }
 
 SparseMatrix reduceToEchelonFormShrawanDelayedModulus(
@@ -733,7 +736,7 @@ SparseMatrix reduceToEchelonFormShrawanDelayedModulus(
   const auto colCount = toReduce.computeColCount();
 
   // Convert input matrix to dense format
-  std::vector<std::vector<SparseMatrix::Scalar>> matrix(rowCount);
+  ::std::vector< ::std::vector<SparseMatrix::Scalar>> matrix(rowCount);
   for (SparseMatrix::RowIndex row = 0; row < rowCount; ++row) {
     MATHICGB_ASSERT(!toReduce.emptyRow(row));
     matrix[row].resize(colCount);
@@ -759,7 +762,7 @@ SparseMatrix reduceToEchelonFormShrawanDelayedModulus(
     if (!rowIsZero)
       reduced.rowDone();
   }
-  return std::move(reduced);
+  return ::std::move(reduced);
 }
 
 SparseMatrix F4MatrixReducer::reduceToBottomRight(const QuadMatrix& matrix) {
@@ -815,12 +818,14 @@ namespace {
     // this assert has to be NO_ASSUME as otherwise the branch below will get
     // optimized out.
     MATHICGB_ASSERT_NO_ASSUME(modulus <=
-      std::numeric_limits<SparseMatrix::Scalar>::max());
-    if (modulus > std::numeric_limits<SparseMatrix::Scalar>::max())
-      throw std::overflow_error("Too large modulus in F4 matrix reduction.");
+      ::std::numeric_limits<SparseMatrix::Scalar>::max());
+    if (modulus > ::std::numeric_limits<SparseMatrix::Scalar>::max())
+      throw ::std::overflow_error("Too large modulus in F4 matrix reduction.");
     return static_cast<SparseMatrix::Scalar>(modulus);
   }
 }
 
 F4MatrixReducer::F4MatrixReducer(const coefficient modulus):
   mModulus(checkModulus(modulus)) {}
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/F4MatrixReducer.hpp b/src/mathicgb/F4MatrixReducer.hpp
index 92b2f33..29e2d42 100755
--- a/src/mathicgb/F4MatrixReducer.hpp
+++ b/src/mathicgb/F4MatrixReducer.hpp
@@ -1,39 +1,45 @@
-#ifndef F4_MATRIX_REDUCER_GUARD
-#define F4_MATRIX_REDUCER_GUARD
-
-#include "SparseMatrix.hpp"
-class QuadMatrix;
-class PolyRing;
-
-/// Class that reduces an F4 matrix represented as a QuadMatrix. The
-/// answer that you get is the submatrix that contains new pivots.
-///
-/// All QuadMatrix parameters passed into methods on this class are
-/// assumed to have a permutation of the top rows and left columns so
-/// that the top left matrix is upper unitriangular. In this way the
-/// lower left part of the matrix becomes all-zero after row reduction.
-class F4MatrixReducer {
-public:
-  /// The ring used is Z/pZ where modulus is the prime p.
-  ///
-  ///
-  F4MatrixReducer(coefficient modulus);
-
-  /// Reduces the bottom rows by the top rows and returns the bottom right
-  /// submatrix of the resulting quad matrix. The lower left submatrix
-  /// is not returned because it is always zero after row reduction.
-  SparseMatrix reduceToBottomRight(const QuadMatrix& matrix);
-
-  /// Returns the reduced row echelon form of matrix.
-  SparseMatrix reducedRowEchelonForm(const SparseMatrix& matrix);
-
-  /// Returns the lower right submatrix of the reduced row echelon
-  /// form of matrix. The lower left part is not returned because it is
-  /// always zero after row reduction.
-  SparseMatrix reducedRowEchelonFormBottomRight(const QuadMatrix& matrix);
-
-private:
-  const SparseMatrix::Scalar mModulus;
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_F4_MATRIX_REDUCER_GUARD
+#define MATHICGB_F4_MATRIX_REDUCER_GUARD
+
+#include "SparseMatrix.hpp"
+
+MATHICGB_NAMESPACE_BEGIN
+
+class QuadMatrix;
+class PolyRing;
+
+/// Class that reduces an F4 matrix represented as a QuadMatrix. The
+/// answer that you get is the submatrix that contains new pivots.
+///
+/// All QuadMatrix parameters passed into methods on this class are
+/// assumed to have a permutation of the top rows and left columns so
+/// that the top left matrix is upper unitriangular. In this way the
+/// lower left part of the matrix becomes all-zero after row reduction.
+class F4MatrixReducer {
+public:
+  /// The ring used is Z/pZ where modulus is the prime p.
+  ///
+  ///
+  F4MatrixReducer(coefficient modulus);
+
+  /// Reduces the bottom rows by the top rows and returns the bottom right
+  /// submatrix of the resulting quad matrix. The lower left submatrix
+  /// is not returned because it is always zero after row reduction.
+  SparseMatrix reduceToBottomRight(const QuadMatrix& matrix);
+
+  /// Returns the reduced row echelon form of matrix.
+  SparseMatrix reducedRowEchelonForm(const SparseMatrix& matrix);
+
+  /// Returns the lower right submatrix of the reduced row echelon
+  /// form of matrix. The lower left part is not returned because it is
+  /// always zero after row reduction.
+  SparseMatrix reducedRowEchelonFormBottomRight(const QuadMatrix& matrix);
+
+private:
+  const SparseMatrix::Scalar mModulus;
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/F4ProtoMatrix.cpp b/src/mathicgb/F4ProtoMatrix.cpp
old mode 100644
new mode 100755
index 66a0499..90d0f65
--- a/src/mathicgb/F4ProtoMatrix.cpp
+++ b/src/mathicgb/F4ProtoMatrix.cpp
@@ -1,6 +1,10 @@
-#include "stdinc.h"
-#include "F4ProtoMatrix.hpp"
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "stdinc.h"
+#include "F4ProtoMatrix.hpp"
+
+MATHICGB_NAMESPACE_BEGIN
+
 auto F4ProtoMatrix::row(const RowIndex row) const -> Row {
   MATHICGB_ASSERT(row < mRows.size());
   const auto& r = mRows[row];
@@ -16,15 +20,15 @@ auto F4ProtoMatrix::row(const RowIndex row) const -> Row {
   }
   return rr;
 }
-
+
 auto F4ProtoMatrix::makeRowWithTheseScalars(const Poly& scalars) -> ColIndex*
 {
-  MATHICGB_ASSERT(rowCount() < std::numeric_limits<RowIndex>::max());
-  MATHICGB_ASSERT(scalars.termCount() < std::numeric_limits<ColIndex>::max());
+  MATHICGB_ASSERT(rowCount() < ::std::numeric_limits<RowIndex>::max());
+  MATHICGB_ASSERT(scalars.termCount() < ::std::numeric_limits<ColIndex>::max());
 
   InternalRow row;
   row.indicesBegin = mIndices.size();
-  row.scalarsBegin = std::numeric_limits<decltype(row.scalarsBegin)>::max();
+  row.scalarsBegin = ::std::numeric_limits<decltype(row.scalarsBegin)>::max();
   row.entryCount = static_cast<ColIndex>(scalars.termCount());
   row.externalScalars = scalars.coefficientBegin();
   mRows.push_back(row);
@@ -33,8 +37,8 @@ auto F4ProtoMatrix::makeRowWithTheseScalars(const Poly& scalars) -> ColIndex*
   return mIndices.data() + row.indicesBegin;
 }
 
-auto F4ProtoMatrix::makeRow(ColIndex entryCount) -> std::pair<ColIndex*, Scalar*> {
-  MATHICGB_ASSERT(rowCount() < std::numeric_limits<RowIndex>::max());
+auto F4ProtoMatrix::makeRow(ColIndex entryCount) -> ::std::pair<ColIndex*, Scalar*> {
+  MATHICGB_ASSERT(rowCount() < ::std::numeric_limits<RowIndex>::max());
 
   InternalRow row;
   row.indicesBegin = mIndices.size();
@@ -45,7 +49,7 @@ auto F4ProtoMatrix::makeRow(ColIndex entryCount) -> std::pair<ColIndex*, Scalar*
 
   mIndices.resize(mIndices.size() + entryCount);
   mScalars.resize(mScalars.size() + entryCount);
-  return std::make_pair(
+  return ::std::make_pair(
     mIndices.data() + row.indicesBegin,
     mScalars.data() + row.scalarsBegin
   );
@@ -61,3 +65,5 @@ void F4ProtoMatrix::removeLastEntries(const RowIndex row, const ColIndex count)
   if (mRows[row].externalScalars == 0)
     mScalars.resize(mScalars.size() - count);
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/F4ProtoMatrix.hpp b/src/mathicgb/F4ProtoMatrix.hpp
old mode 100644
new mode 100755
index cff26d0..cb5f797
--- a/src/mathicgb/F4ProtoMatrix.hpp
+++ b/src/mathicgb/F4ProtoMatrix.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_F4_PROTO_MATRIX_GUARD
 #define MATHICGB_F4_PROTO_MATRIX_GUARD
 
@@ -5,6 +7,8 @@
 #include "SparseMatrix.hpp"
 #include "Poly.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 class F4ProtoMatrix {
 public:
   typedef uint32 RowIndex;
@@ -25,7 +29,7 @@ public:
 
   ColIndex* makeRowWithTheseScalars(const Poly& scalars);
 
-  std::pair<ColIndex*, Scalar*> makeRow(ColIndex entryCount);
+  ::std::pair<ColIndex*, Scalar*> makeRow(ColIndex entryCount);
 
   void removeLastEntries(const RowIndex row, const ColIndex count);
 
@@ -37,9 +41,10 @@ private:
     const ExternalScalar* externalScalars;
   };
 
-  std::vector<ColIndex> mIndices;
-  std::vector<Scalar> mScalars;
-  std::vector<InternalRow> mRows;
+  ::std::vector<ColIndex> mIndices;
+  ::std::vector<Scalar> mScalars;
+  ::std::vector<InternalRow> mRows;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
index 4d8f563..ae5c3ca 100755
--- a/src/mathicgb/F4Reducer.cpp
+++ b/src/mathicgb/F4Reducer.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "F4Reducer.hpp"
 
@@ -41,6 +43,8 @@ MATHICGB_DEFINE_LOG_ALIAS(
   "F4MatReduceTop,F4RedBottomRight"
 );
 
+MATHICGB_NAMESPACE_BEGIN
+
 F4Reducer::F4Reducer(const PolyRing& ring, Type type):
   mType(type),
   mFallback(Reducer::makeReducer(Reducer::Reducer_BjarkeGeo, ring)),
@@ -55,58 +59,58 @@ size_t F4Reducer::preferredSetSize() const {
   return 100000;
 }
 
-void F4Reducer::writeMatricesTo(std::string file, size_t minEntries) {
-  mStoreToFile = std::move(file);
+void F4Reducer::writeMatricesTo(::std::string file, size_t minEntries) {
+  mStoreToFile = ::std::move(file);
   mMinEntryCountForStore = minEntries;
   mMatrixSaveCount = 0;
 }
 
-std::unique_ptr<Poly> F4Reducer::classicReduce
+::std::unique_ptr<Poly> F4Reducer::classicReduce
 (const Poly& poly, const PolyBasis& basis) {
   if (tracingLevel >= 2)
-    std::cerr <<
+    ::std::cerr <<
       "F4Reducer: Using fall-back reducer for single classic reduction\n";
 
   auto p = mFallback->classicReduce(poly, basis);
   mSigStats = mFallback->sigStats();
   mClassicStats = mFallback->classicStats();
-  return std::move(p);
+  return ::std::move(p);
 }
 
-std::unique_ptr<Poly> F4Reducer::classicTailReduce
+::std::unique_ptr<Poly> F4Reducer::classicTailReduce
 (const Poly& poly, const PolyBasis& basis) {
   if (tracingLevel >= 2)
-    std::cerr <<
+    ::std::cerr <<
       "F4Reducer: Using fall-back reducer for single classic tail reduction\n";
 
   auto p = mFallback->classicTailReduce(poly, basis);
   mSigStats = mFallback->sigStats();
   mClassicStats = mFallback->classicStats();
-  return std::move(p);
+  return ::std::move(p);
 }
 
-std::unique_ptr<Poly> F4Reducer::classicReduceSPoly(
+::std::unique_ptr<Poly> F4Reducer::classicReduceSPoly(
   const Poly& a,
   const Poly& b,
   const PolyBasis& basis
 ) {
   if (tracingLevel >= 2)
-    std::cerr << "F4Reducer: "
+    ::std::cerr << "F4Reducer: "
       "Using fall-back reducer for single classic S-pair reduction\n";
   auto p = mFallback->classicReduceSPoly(a, b, basis);
   mSigStats = mFallback->sigStats();
   mClassicStats = mFallback->classicStats();
-  return std::move(p);
+  return ::std::move(p);
 }
 
 void F4Reducer::classicReduceSPolySet(
-  std::vector<std::pair<size_t, size_t> >& spairs,
+  ::std::vector< ::std::pair<size_t, size_t> >& spairs,
   const PolyBasis& basis,
-  std::vector<std::unique_ptr<Poly> >& reducedOut
+  ::std::vector< ::std::unique_ptr<Poly> >& reducedOut
 ) {
   if (spairs.size() <= 1 && false) {
     if (tracingLevel >= 2)
-      std::cerr << "F4Reducer: Using fall-back reducer for "
+      ::std::cerr << "F4Reducer: Using fall-back reducer for "
         << spairs.size() << " S-pairs.\n";
     mFallback->classicReduceSPolySet(spairs, basis, reducedOut);
     mSigStats = mFallback->sigStats();
@@ -117,10 +121,10 @@ void F4Reducer::classicReduceSPolySet(
 
   MATHICGB_ASSERT(!spairs.empty());
   if (tracingLevel >= 2 && false)
-    std::cerr << "F4Reducer: Reducing " << spairs.size() << " S-polynomials.\n";
+    ::std::cerr << "F4Reducer: Reducing " << spairs.size() << " S-polynomials.\n";
 
   SparseMatrix reduced;
-  std::vector<monomial> monomials;
+  ::std::vector<monomial> monomials;
   {
     QuadMatrix qm;
     {
@@ -147,20 +151,20 @@ void F4Reducer::classicReduceSPolySet(
     saveMatrix(qm);
     reduced = F4MatrixReducer(basis.ring().charac()).
       reducedRowEchelonFormBottomRight(qm);
-    monomials = std::move(qm.rightColumnMonomials);
+    monomials = ::std::move(qm.rightColumnMonomials);
     const auto end = qm.leftColumnMonomials.end();
     for (auto it = qm.leftColumnMonomials.begin(); it != end; ++it)
       mRing.freeMonomial(*it);
   }
 
   if (tracingLevel >= 2 && false)
-    std::cerr << "F4Reducer: Extracted " << reduced.rowCount()
+    ::std::cerr << "F4Reducer: Extracted " << reduced.rowCount()
               << " non-zero rows\n";
 
   for (SparseMatrix::RowIndex row = 0; row < reduced.rowCount(); ++row) {
     auto p = make_unique<Poly>(basis.ring());
     reduced.rowToPolynomial(row, monomials, *p);
-    reducedOut.push_back(std::move(p));
+    reducedOut.push_back(::std::move(p));
   }
   const auto end = monomials.end();
   for (auto it = monomials.begin(); it != end; ++it)
@@ -168,13 +172,13 @@ void F4Reducer::classicReduceSPolySet(
 }
 
 void F4Reducer::classicReducePolySet
-(const std::vector<std::unique_ptr<Poly> >& polys,
+(const ::std::vector< ::std::unique_ptr<Poly> >& polys,
  const PolyBasis& basis,
- std::vector<std::unique_ptr<Poly> >& reducedOut)
+ ::std::vector< ::std::unique_ptr<Poly> >& reducedOut)
 {
   if (polys.size() <= 1 && false) {
     if (tracingLevel >= 2)
-      std::cerr << "F4Reducer: Using fall-back reducer for "
+      ::std::cerr << "F4Reducer: Using fall-back reducer for "
                 << polys.size() << " polynomials.\n";
     mFallback->classicReducePolySet(polys, basis, reducedOut);
     mSigStats = mFallback->sigStats();
@@ -186,10 +190,10 @@ void F4Reducer::classicReducePolySet
 
   MATHICGB_ASSERT(!polys.empty());
   if (tracingLevel >= 2 && false)
-    std::cerr << "F4Reducer: Reducing " << polys.size() << " polynomials.\n";
+    ::std::cerr << "F4Reducer: Reducing " << polys.size() << " polynomials.\n";
 
   SparseMatrix reduced;
-  std::vector<monomial> monomials;
+  ::std::vector<monomial> monomials;
   {
     QuadMatrix qm;
     {
@@ -212,20 +216,20 @@ void F4Reducer::classicReducePolySet
     saveMatrix(qm);
     reduced = F4MatrixReducer(basis.ring().charac()).
       reducedRowEchelonFormBottomRight(qm);
-    monomials = std::move(qm.rightColumnMonomials);
+    monomials = ::std::move(qm.rightColumnMonomials);
     for (auto it = qm.leftColumnMonomials.begin();
       it != qm.leftColumnMonomials.end(); ++it)
       mRing.freeMonomial(*it);
   }
 
   if (tracingLevel >= 2 && false)
-    std::cerr << "F4Reducer: Extracted " << reduced.rowCount()
+    ::std::cerr << "F4Reducer: Extracted " << reduced.rowCount()
               << " non-zero rows\n";
 
   for (SparseMatrix::RowIndex row = 0; row < reduced.rowCount(); ++row) {
     auto p = make_unique<Poly>(basis.ring());
     reduced.rowToPolynomial(row, monomials, *p);
-    reducedOut.push_back(std::move(p));
+    reducedOut.push_back(::std::move(p));
   }
   const auto end = monomials.end();
   for (auto it = monomials.begin(); it != end; ++it)
@@ -239,19 +243,19 @@ Poly* F4Reducer::regularReduce(
   const SigPolyBasis& basis
 ) {
   if (tracingLevel >= 2)
-    std::cerr <<
+    ::std::cerr <<
       "F4Reducer: Using fall-back reducer for single regular reduction\n";
   auto p = mFallback->regularReduce(sig, multiple, basisElement, basis);
   mSigStats = mFallback->sigStats();
   mClassicStats = mFallback->classicStats();
-  return std::move(p);
+  return ::std::move(p);
 }
 
 void F4Reducer::setMemoryQuantum(size_t quantum) {
   mMemoryQuantum = quantum;
 }
 
-std::string F4Reducer::description() const {
+::std::string F4Reducer::description() const {
   return "F4 reducer";
 }
 
@@ -266,12 +270,14 @@ void F4Reducer::saveMatrix(const QuadMatrix& matrix) {
   if (mMinEntryCountForStore > entryCount)
     return;
   ++mMatrixSaveCount;
-  std::ostringstream fileName;
+  ::std::ostringstream fileName;
   fileName << mStoreToFile << '-' << mMatrixSaveCount << ".qmat";
   if (tracingLevel > 2)
-    std::cerr << "F4Reducer: Saving matrix to " << fileName.str() << '\n';
+    ::std::cerr << "F4Reducer: Saving matrix to " << fileName.str() << '\n';
   FILE* file = fopen(fileName.str().c_str(), "wb");
   // @todo: fix leak of file on exception
   matrix.write(static_cast<SparseMatrix::Scalar>(mRing.charac()), file);
   fclose(file);
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/F4Reducer.hpp b/src/mathicgb/F4Reducer.hpp
index 8a07cce..47d7a3d 100755
--- a/src/mathicgb/F4Reducer.hpp
+++ b/src/mathicgb/F4Reducer.hpp
@@ -1,9 +1,14 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_F4_REDUCER_GUARD
 #define MATHICGB_F4_REDUCER_GUARD
 
 #include "Reducer.hpp"
 #include "PolyRing.hpp"
 #include <string>
+
+MATHICGB_NAMESPACE_BEGIN
+
 class QuadMatrix;
 
 class F4Reducer : public Reducer {
@@ -68,9 +73,5 @@ private:
   size_t mMatrixSaveCount; // how many matrices have been saved
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/FixedSizeMonomialMap.h b/src/mathicgb/FixedSizeMonomialMap.h
index fa7a60f..9751e7b 100755
--- a/src/mathicgb/FixedSizeMonomialMap.h
+++ b/src/mathicgb/FixedSizeMonomialMap.h
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_FIXED_SIZE_MONOMIAL_MAP_GUARD
 #define MATHICGB_FIXED_SIZE_MONOMIAL_MAP_GUARD
 
@@ -9,6 +11,8 @@
 #include <vector>
 #include <algorithm>
 
+MATHICGB_NAMESPACE_BEGIN
+
 /// Concurrent hashtable mapping from monomials to T with a fixed number of
 /// buckets. Lookups are lockless while insertions grab a lock.
 ///
@@ -23,7 +27,7 @@ template<class T>
 class FixedSizeMonomialMap {
 public:
   typedef T mapped_type;
-  typedef std::pair<const_monomial, mapped_type> value_type;
+  typedef ::std::pair<const_monomial, mapped_type> value_type;
 
   /// Iterates through entries in the hash table.
   class const_iterator;
@@ -42,7 +46,7 @@ public:
     mRing(ring),
     mNodeAlloc(sizeofNode(ring))
   {
-    // Calling new int[x] does not zero the array. std::atomic has a trivial
+    // Calling new int[x] does not zero the array. ::std::atomic has a trivial
     // constructor so the same thing is true of new atomic[x]. Calling
     // new int[x]() is supposed to zero initialize but this apparently
     // does not work on GCC. So we have to fill the table with nulls
@@ -68,7 +72,7 @@ public:
       make_unique_array<Atomic<Node*>>(hashMaskToBucketCount(mHashToIndexMask))
     ),
     mRing(map.ring()),
-    mNodeAlloc(std::move(map.mNodeAlloc))
+    mNodeAlloc(::std::move(map.mNodeAlloc))
   {
     // We can store relaxed as the constructor does not run concurrently.
     setTableEntriesToNullRelaxed();
@@ -78,7 +82,7 @@ public:
         const size_t index = hashToIndex(mRing.monomialHashValue(node->mono));
         Node* const next = node->next.load();
         node->next.store(mBuckets[index].load());
-        mBuckets[index].store(node, std::memory_order_relaxed);
+        mBuckets[index].store(node, ::std::memory_order_relaxed);
         node = next;
       }
     }
@@ -109,44 +113,44 @@ public:
   /// Returns the value associated to mono or null if there is no such value.
   /// Also returns an internal monomial that equals mono of such a monomial
   /// exists.
-  std::pair<const mapped_type*, ConstMonomial>
+  ::std::pair<const mapped_type*, ConstMonomial>
   find(const const_monomial mono) const {
     const HashValue monoHash = mRing.monomialHashValue(mono);
     const Node* node = bucketAtIndex(hashToIndex(monoHash));
-    for (; node != 0; node = node->next.load(std::memory_order_consume)) {
+    for (; node != 0; node = node->next.load(::std::memory_order_consume)) {
       // To my surprise, it seems to be faster to comment out this branch.
       // I guess the hash table has too few collisions to make it worth it.
       //if (monoHash != mRing.monomialHashValue(node->mono))
       //  continue;
       if (mRing.monomialEqualHintTrue(mono, node->mono))
-        return std::make_pair(&node->value, node->mono);
+        return ::std::make_pair(&node->value, node->mono);
     }
-    return std::make_pair(static_cast<const mapped_type*>(0), ConstMonomial(0));
+    return ::std::make_pair(static_cast<const mapped_type*>(0), ConstMonomial(0));
   }
 
   // As find on the product a*b but also returns the monomial that is the
   // product.
   MATHICGB_INLINE
-  std::pair<const mapped_type*, ConstMonomial> findProduct(
+  ::std::pair<const mapped_type*, ConstMonomial> findProduct(
     const const_monomial a,
     const const_monomial b
   ) const {
     const HashValue abHash = mRing.monomialHashOfProduct(a, b);
     const Node* node = bucketAtIndex(hashToIndex(abHash));
-    for (; node != 0; node = node->next.load(std::memory_order_consume)) {
+    for (; node != 0; node = node->next.load(::std::memory_order_consume)) {
       // To my surprise, it seems to be faster to comment out this branch.
       // I guess the hash table has too few collisions to make it worth it.
       //if (abHash != mRing.monomialHashValue(node->mono))
       //  continue;
       if (mRing.monomialIsProductOfHintTrue(a, b, node->mono))
-        return std::make_pair(&node->value, node->mono);
+        return ::std::make_pair(&node->value, node->mono);
     }
-    return std::make_pair(static_cast<const mapped_type*>(0), ConstMonomial(0));
+    return ::std::make_pair(static_cast<const mapped_type*>(0), ConstMonomial(0));
   }
 
   /// As findProduct but looks for a1*b and a2*b at one time.
   MATHICGB_INLINE
-  std::pair<const mapped_type*, const mapped_type*> findTwoProducts(
+  ::std::pair<const mapped_type*, const mapped_type*> findTwoProducts(
     const const_monomial a1,
     const const_monomial a2,
     const const_monomial b
@@ -159,9 +163,9 @@ public:
     if (node1 != 0 && node2 != 0 && mRing.monomialIsTwoProductsOfHintTrue
       (a1, a2, b, node1->mono, node2->mono)
     )
-      return std::make_pair(&node1->value, &node2->value);
+      return ::std::make_pair(&node1->value, &node2->value);
     else
-      return std::make_pair(findProduct(a1, b).first, findProduct(a2, b).first);
+      return ::std::make_pair(findProduct(a1, b).first, findProduct(a2, b).first);
   }
 
   /// Makes value.first map to value.second unless value.first is already
@@ -172,7 +176,7 @@ public:
   /// inserted value equals the already present value.
   ///
   /// p.first.second is a internal monomial that equals value.first.
-  std::pair<std::pair<const mapped_type*, ConstMonomial>, bool>
+  ::std::pair< ::std::pair<const mapped_type*, ConstMonomial>, bool>
   insert(const value_type& value) {
     const mgb::tbb::mutex::scoped_lock lockGuard(mInsertionMutex);
     // find() loads buckets with memory_order_consume, so it may seem like
@@ -186,7 +190,7 @@ public:
     {
       const auto found = find(value.first);
       if (found.first != 0)
-        return std::make_pair(found, false); // key already present
+        return ::std::make_pair(found, false); // key already present
     }
 
     const auto node = static_cast<Node*>(mNodeAlloc.alloc());
@@ -201,8 +205,8 @@ public:
     // we cannot store with memory_order_relaxed here because unlocking the
     // lock only synchronizes with threads who later grab the lock - it does
     // not synchronize with reading threads since they do not grab the lock.
-    mBuckets[index].store(node, std::memory_order_release);
-    return std::make_pair(std::make_pair(&node->value, node->mono), true); // successful insertion
+    mBuckets[index].store(node, ::std::memory_order_release);
+    return ::std::make_pair(::std::make_pair(&node->value, node->mono), true); // successful insertion
   }
 
   /// This operation removes all entries from the table. This operation
@@ -231,7 +235,7 @@ private:
   void setTableEntriesToNullRelaxed() {
     const auto tableEnd = mBuckets.get() + bucketCount();
     for (auto tableIt = mBuckets.get(); tableIt != tableEnd; ++tableIt)
-      tableIt->store(0, std::memory_order_relaxed);
+      tableIt->store(0, ::std::memory_order_relaxed);
   }
 
   struct Node {
@@ -253,7 +257,7 @@ private:
     // possible number of buckets based on the range of the hash
     // value type. Only unsigned overflow is defined, so we need
     // to assert that the hash type is unsigned.
-    static_assert(!std::numeric_limits<HashValue>::is_signed, "");
+    static_assert(!::std::numeric_limits<HashValue>::is_signed, "");
     const auto hashToIndexMask = static_cast<HashValue>(pow2 - 1);
     MATHICGB_ASSERT(pow2 == hashMaskToBucketCount(hashToIndexMask));
     return hashToIndexMask;
@@ -277,16 +281,16 @@ private:
 
   Node* bucketAtIndex(size_t index) {
     MATHICGB_ASSERT(index < bucketCount());
-    return mBuckets[index].load(std::memory_order_consume);
+    return mBuckets[index].load(::std::memory_order_consume);
   }
 
   const Node* bucketAtIndex(size_t index) const {
     MATHICGB_ASSERT(index < bucketCount());
-    return mBuckets[index].load(std::memory_order_consume);
+    return mBuckets[index].load(::std::memory_order_consume);
   }
 
   const HashValue mHashToIndexMask;
-  std::unique_ptr<Atomic<Node*>[]> const mBuckets;
+  ::std::unique_ptr<Atomic<Node*>[]> const mBuckets;
   const PolyRing& mRing;
   memt::BufferPool mNodeAlloc; // nodes are allocated from here.
   mgb::tbb::mutex mInsertionMutex;
@@ -294,8 +298,8 @@ private:
 public:
   class const_iterator {
   public:
-    typedef std::forward_iterator_tag iterator_category;
-    typedef std::pair<mapped_type, ConstMonomial> value_type;
+    typedef ::std::forward_iterator_tag iterator_category;
+    typedef ::std::pair<mapped_type, ConstMonomial> value_type;
     typedef ptrdiff_t difference_type;
 	typedef size_t distance_type;
 	typedef value_type* pointer;
@@ -306,7 +310,7 @@ public:
     const_iterator& operator++() {
       MATHICGB_ASSERT(mNode != 0);
       MATHICGB_ASSERT(mBucket != mBucketsEnd);
-      const Node* const node = mNode->next.load(std::memory_order_consume);
+      const Node* const node = mNode->next.load(::std::memory_order_consume);
       if (node != 0)
         mNode = node;
       else
@@ -325,7 +329,7 @@ public:
 
     const value_type operator*() const {
       MATHICGB_ASSERT(mNode != 0);
-      return std::make_pair(mNode->value, mNode->mono);
+      return ::std::make_pair(mNode->value, mNode->mono);
     }
 
   private:
@@ -341,7 +345,7 @@ public:
         mNode = 0;
         return;
       }
-      const Node* const node = bucketBegin->load(std::memory_order_consume);
+      const Node* const node = bucketBegin->load(::std::memory_order_consume);
       if (node != 0)
         mNode = node;
       else
@@ -356,7 +360,7 @@ public:
           mNode = 0;
           break;
         }
-        const Node* const node = mBucket->load(std::memory_order_consume);
+        const Node* const node = mBucket->load(::std::memory_order_consume);
         if (node != 0) {
           mNode = node;
           break;
@@ -374,4 +378,6 @@ public:
   };
 };
 
+MATHICGB_NAMESPACE_END
+
 #endif
diff --git a/src/mathicgb/HashTourReducer.cpp b/src/mathicgb/HashTourReducer.cpp
index ba990a1..9a1bd21 100755
--- a/src/mathicgb/HashTourReducer.cpp
+++ b/src/mathicgb/HashTourReducer.cpp
@@ -1,10 +1,12 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "HashTourReducer.hpp"
 
 #include <utility>
 
+MATHICGB_NAMESPACE_BEGIN
+
 HashTourReducer::HashTourReducer(const PolyRing& ring):
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
@@ -209,8 +211,4 @@ void HashTourReducer::dump() const
 {
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
-
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/HashTourReducer.hpp b/src/mathicgb/HashTourReducer.hpp
index 8953679..234bad9 100755
--- a/src/mathicgb/HashTourReducer.hpp
+++ b/src/mathicgb/HashTourReducer.hpp
@@ -1,13 +1,15 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
-#ifndef _hash_tour_reducer_h_
-#define _hash_tour_reducer_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_HASH_TOUR_REDUCER_GUARD
+#define MATHICGB_HASH_TOUR_REDUCER_GUARD
 
 #include "TypicalReducer.hpp"
 #include "PolyHashTable.hpp"
 #include <mathic.h>
 #include <memtailor.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class HashTourReducer : public TypicalReducer {
 public:
   HashTourReducer(const PolyRing& R);
@@ -80,9 +82,5 @@ private:
   memt::BufferPool mPool;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/KoszulQueue.cpp b/src/mathicgb/KoszulQueue.cpp
deleted file mode 100755
index 3a4daca..0000000
--- a/src/mathicgb/KoszulQueue.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "stdinc.h"
-#include "KoszulQueue.hpp"
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/KoszulQueue.hpp b/src/mathicgb/KoszulQueue.hpp
index 78986e7..bec77cb 100755
--- a/src/mathicgb/KoszulQueue.hpp
+++ b/src/mathicgb/KoszulQueue.hpp
@@ -1,10 +1,14 @@
-#ifndef koszul_queue_guard
-#define koszul_queue_guard
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_KOSZUL_QUEUE_GUARD
+#define MATHICGB_KOSZUL_QUEUE_GUARD
 
 #include "PolyRing.hpp"
 #include "NonCopyable.hpp"
 #include <mathic.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class KoszulQueue : public NonCopyable<KoszulQueue> {
 public:
   typedef PolyRing::Monoid Monoid;
@@ -78,4 +82,5 @@ private:
   mic::Heap<Configuration> mQueue;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/LogDomain.cpp b/src/mathicgb/LogDomain.cpp
index 74e9012..006a073 100755
--- a/src/mathicgb/LogDomain.cpp
+++ b/src/mathicgb/LogDomain.cpp
@@ -1,109 +1,115 @@
-#include "stdinc.h"
-#include "LogDomain.hpp"
-
-#include "LogDomainSet.hpp"
-#include <mathic.h>
-#include <iostream>
-
-static const auto logDomainGlobalStartTime = mgb::tbb::tick_count::now();
-
-LogDomain<true>::LogDomain(
-  const char* const name,
-  const char* const description,
-  const bool enabled,
-  const bool streamEnabled
-):
-  mEnabled(enabled),
-  mOriginallyEnabled(enabled),
-  mStreamEnabled(streamEnabled),
-  mOriginallyStreamEnabled(streamEnabled),
-  mName(name),
-  mDescription(description),
-  mInterval(),
-  mHasTime(false),
-  mCount(0),
-  mHasCount(false)
-{
-  LogDomainSet::singleton().registerLogDomain(*this);
-}
-
-void LogDomain<true>::reset() {
-  mEnabled = mOriginallyEnabled;
-  mStreamEnabled = mOriginallyStreamEnabled;
-  mInterval = TimeInterval();
-  mHasTime = false;
-  mCount = 0;
-  mHasCount = false;
-}
-
-std::ostream& LogDomain<true>::stream() {
-  return std::cerr;
-}
-
-LogDomain<true>::Timer LogDomain<true>::timer() {
-  return Timer(*this);
-}
-
-double LogDomain<true>::loggedSecondsReal() const {
-  return mInterval.realSeconds;
-}
-
-void LogDomain<true>::TimeInterval::print(std::ostream& out) const {
-  const auto oldFlags = out.flags();
-  const auto oldPrecision = out.precision();
-  out.precision(3);
-  out << std::fixed << realSeconds << "s (real)";
-  // todo: restore the stream state using RAII, since the above code might
-  // throw an exception.
-  out.precision(oldPrecision);
-  out.flags(oldFlags);
-}
-
-void LogDomain<true>::recordTime(TimeInterval interval) {
-  if (!enabled())
-    return;
-  mInterval.realSeconds += interval.realSeconds;
-  mHasTime = true;
-
-  if (streamEnabled()) {
-    MATHICGB_ASSERT(mName != 0);
-    stream() << mName << " time recorded:        ";
-    interval.print(stream());
-    stream() << std::endl;
-  }
-}
-
-LogDomain<true>::Timer::Timer(LogDomain<true>& logger):
-  mLogger(logger),
-  mTimerRunning(false),
-  mRealTicks()
-{
-  start();
-}
-
-LogDomain<true>::Timer::~Timer() {
-  stop();
-}
-
-void LogDomain<true>::Timer::stop() {
-  if (!running())
-    return;
-  mTimerRunning = false;
-  if (!mLogger.enabled())
-    return;
-  TimeInterval interval;
-  interval.realSeconds = (mgb::tbb::tick_count::now() - mRealTicks).seconds();
-  mLogger.recordTime(interval);
-  return;
-}
-
-void LogDomain<true>::Timer::start() {
-  if (!mLogger.enabled() || mTimerRunning)
-    return;
-  mTimerRunning = true;
-  mRealTicks = mgb::tbb::tick_count::now();
-}
-
-LogDomainInternal::LogAliasRegisterer::LogAliasRegisterer(const char* alias, const char* of) {
-  LogDomainSet::singleton().registerLogAlias(alias, of);
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "stdinc.h"
+#include "LogDomain.hpp"
+
+#include "LogDomainSet.hpp"
+#include <mathic.h>
+#include <iostream>
+
+MATHICGB_NAMESPACE_BEGIN
+
+static const auto logDomainGlobalStartTime = mgb::tbb::tick_count::now();
+
+LogDomain<true>::LogDomain(
+  const char* const name,
+  const char* const description,
+  const bool enabled,
+  const bool streamEnabled
+):
+  mEnabled(enabled),
+  mOriginallyEnabled(enabled),
+  mStreamEnabled(streamEnabled),
+  mOriginallyStreamEnabled(streamEnabled),
+  mName(name),
+  mDescription(description),
+  mInterval(),
+  mHasTime(false),
+  mCount(0),
+  mHasCount(false)
+{
+  LogDomainSet::singleton().registerLogDomain(*this);
+}
+
+void LogDomain<true>::reset() {
+  mEnabled = mOriginallyEnabled;
+  mStreamEnabled = mOriginallyStreamEnabled;
+  mInterval = TimeInterval();
+  mHasTime = false;
+  mCount = 0;
+  mHasCount = false;
+}
+
+std::ostream& LogDomain<true>::stream() {
+  return std::cerr;
+}
+
+LogDomain<true>::Timer LogDomain<true>::timer() {
+  return Timer(*this);
+}
+
+double LogDomain<true>::loggedSecondsReal() const {
+  return mInterval.realSeconds;
+}
+
+void LogDomain<true>::TimeInterval::print(std::ostream& out) const {
+  const auto oldFlags = out.flags();
+  const auto oldPrecision = out.precision();
+  out.precision(3);
+  out << std::fixed << realSeconds << "s (real)";
+  // todo: restore the stream state using RAII, since the above code might
+  // throw an exception.
+  out.precision(oldPrecision);
+  out.flags(oldFlags);
+}
+
+void LogDomain<true>::recordTime(TimeInterval interval) {
+  if (!enabled())
+    return;
+  mInterval.realSeconds += interval.realSeconds;
+  mHasTime = true;
+
+  if (streamEnabled()) {
+    MATHICGB_ASSERT(mName != 0);
+    stream() << mName << " time recorded:        ";
+    interval.print(stream());
+    stream() << std::endl;
+  }
+}
+
+LogDomain<true>::Timer::Timer(LogDomain<true>& logger):
+  mLogger(logger),
+  mTimerRunning(false),
+  mRealTicks()
+{
+  start();
+}
+
+LogDomain<true>::Timer::~Timer() {
+  stop();
+}
+
+void LogDomain<true>::Timer::stop() {
+  if (!running())
+    return;
+  mTimerRunning = false;
+  if (!mLogger.enabled())
+    return;
+  TimeInterval interval;
+  interval.realSeconds = (mgb::tbb::tick_count::now() - mRealTicks).seconds();
+  mLogger.recordTime(interval);
+  return;
+}
+
+void LogDomain<true>::Timer::start() {
+  if (!mLogger.enabled() || mTimerRunning)
+    return;
+  mTimerRunning = true;
+  mRealTicks = mgb::tbb::tick_count::now();
+}
+
+LogDomainInternal::LogAliasRegisterer::LogAliasRegisterer(const char* alias, const char* of) {
+  LogDomainSet::singleton().registerLogAlias(alias, of);
+}
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/LogDomain.hpp b/src/mathicgb/LogDomain.hpp
index 8e4156f..8fd741d 100755
--- a/src/mathicgb/LogDomain.hpp
+++ b/src/mathicgb/LogDomain.hpp
@@ -1,329 +1,335 @@
-#ifndef MATHICGB_LOG_DOMAIN_GUARD
-#define MATHICGB_LOG_DOMAIN_GUARD
-
-#include "mtbb.hpp"
-#include <ostream>
-#include <ctime>
-#include <sstream>
-
-/// A named area of logging that can be turned on or off at runtime and at
-/// compile time.
-///
-/// A logger that is turned off at compile time emits no code
-/// into the executable and all the code that writes to that logger is also
-/// removed by the optimizer if it is written in the correct way. Use the
-/// logging macroes to ensure proper use so that compile-time disabled
-/// LogDomains properly have zero overhead. LogDomains can be turned on
-/// and off at compile time and at runtime individually.
-///
-/// Compile-time enabled loggers automatically register themselves at start-up
-/// with LogDomainSet::singleton().
-///
-/// @todo: support turning all loggers off globally with a macro, regardless
-/// of their individual compile-time on/off setting.
-
-template<bool CompileTimeEnabled>
-class LogDomain {};
-
-template<>
-class LogDomain<true> {
-public:
-  static const bool compileTimeEnabled = true;
-
-  LogDomain(
-    const char* const name,
-    const char* const description,
-    const bool enabled,
-    const bool streamEnabled
-  );
-
-  const char* name() const {return mName;}
-  const char* description() const {return mDescription;}
-  bool enabled() const {return mEnabled;}
-  bool streamEnabledPure() const {return mStreamEnabled;}
-  bool streamEnabled() const {return enabled() && streamEnabledPure();}
-
-  void setEnabled(const bool enabled) {mEnabled = enabled;}
-  void setStreamEnabled(const bool enabled) {mStreamEnabled = enabled;}
-
-  std::ostream& stream();
-
-  /// Class for recording time that is logged. Movable.
-  class Timer;
-
-  /// Returns a started timer.
-  Timer timer();
-
-  /// Returns true if any time has been logged on this logger, even if the
-  /// duration of that time was zero (that is., less than the resolution
-  /// of the timer).
-  bool hasTime() const {return mHasTime;}
-
-  double loggedSecondsReal() const;
-
-
-  typedef unsigned long long Counter;
-
-  Counter count() const {return mCount;}
-
-  void setCount(const Counter counter) {
-    if (enabled()) {
-      mCount = counter;
-      mHasCount = true;
-    }
-  }
-
-  /// Returns true if setCount has been called.
-  bool hasCount() const {return mHasCount;}
-
-  /// Resets this object to the state it had when it was
-  /// constructed.
-  void reset();
-
-private:
-  struct TimeInterval {
-    // todo: support user time too. clock() doesn't seem to sum the time
-    // for all threads, so that didn't work.
-    double realSeconds;
-
-    void print(std::ostream& out) const;
-  };
-  void recordTime(TimeInterval interval);
-
-  bool mEnabled;
-  const bool mOriginallyEnabled;
-  bool mStreamEnabled;
-  const bool mOriginallyStreamEnabled;
-  const char* mName;
-  const char* mDescription;
-
-  TimeInterval mInterval; /// Total amount of time recorded on this log.
-  bool mHasTime; /// Whether any time has been registered (even if 0s).
-
-  Counter mCount;
-  bool mHasCount; /// Whether the count has been set (even if set to zero)
-};
-
-class LogDomain<true>::Timer {
-public:
-  /// Start the timer running. The elapsed time will be logged to the logger
-  /// once the timer is stopped or destructed.
-  Timer(LogDomain<true>& logger);
-
-  /// Stops the timer.
-  ~Timer();
-
-  /// Returns true if the timer is currently recording time.
-  bool running() const {return mTimerRunning;}
-
-  /// Stops recording time and logs the elapsed time to the logger.
-  ///
-  /// This is a no-op if the timer is not running. If the logger
-  /// is disabled then no time is logged.
-  void stop();
-
-  /// Start recording time on a stopped timer.
-  ///
-  /// This is a no-op if the timer is already running or if the logger is
-  /// disabled.
-  void start();
-
-private:
-  LogDomain<true>& mLogger;
-  bool mTimerRunning;
-  mgb::tbb::tick_count mRealTicks; // high precision
-};
-
-/// This is a compile-time disabled logger. You are not supposed to dynamically
-/// call any non-const methods on it other than the constructor. Code that
-/// calls other code will compile but it is an error if any of those
-/// methods get called at runtime.
-template<>
-class LogDomain<false> {
-public:
-  static const bool compileTimeEnabled = false;
-
-  LogDomain(const char* const, const char* const, const bool) {}
-
-  bool enabled() const {return false;}
-  bool streamEnabled() const {return false;}
-
-  class Timer {
-  public:
-    Timer(LogDomain<false>&) {}
-    bool running() const {return false;}
-    void stop() {MATHICGB_ASSERT(false);}
-    void start() {MATHICGB_ASSERT(false);}
-  };
-  Timer timer() {
-    MATHICGB_ASSERT(false);
-    return Timer(*this);
-  }
-
-  std::ostream& stream() {
-    MATHICGB_ASSERT(false);
-    return *static_cast<std::ostream*>(0);
-  }
-
-  typedef unsigned long long Counter;
-  Counter count() const {return 0;}
-  void setCount(const Counter counter) {MATHICGB_ASSERT(false);}
-  bool hasCount() const {return false;}
-  void reset() {}
-};
-
-namespace LogDomainInternal {
-  // Helpers for the logging macroes
-
-  template<class Tag, bool Default>
-  struct SelectValue {static const bool value = Default;};
-
-  template<class> struct Tag_ {};
-  template<class> struct Tag_0 {};
-  template<class> struct Tag_1 {};
-
-  template<bool Default>
-  struct SelectValue<Tag_0<int>, Default> {static const bool value = false;};
-
-  template<bool Default>
-  struct SelectValue<Tag_1<int>, Default> {static const bool value = true;};
-
-  template<class L>
-  struct LambdaRunner {L& log;};
-  template<class L>
-  LambdaRunner<L> lambdaRunner(L& l) {
-    LambdaRunner<L> r = {l};
-    return r;
-  }
-  template<class L, class T>
-  void operator+(LambdaRunner<L> runner, T&& lambda) {
-    lambda(runner.log, runner.log.stream());
-  }
-
-  struct LogAliasRegisterer {
-    LogAliasRegisterer(const char* alias, const char* of);
-  };
-}
-
-/// Defines LogDomainInternal::value_##NAME to be equal to the value of
-/// the macro MATHICGB_LOG_##NAME if that macro expands to 0 or 1. Otherwise
-/// the macro MATHICGB_LOG_##NAME is ignored and instead DEFAULT_VALUE is used.
-#define MATHICGB_CAPTURE_LOG_ENABLED(NAME, DEFAULT_VALUE) \
-  namespace LogDomainInternal { \
-    template<class> struct Tag_MATHICGB_LOG_##NAME {}; \
-    typedef MATHICGB_CONCATENATE_AFTER_EXPANSION(Tag_, MATHICGB_LOG_##NAME)<int> \
-      SelectedTag_##NAME; \
-    static const bool value_##NAME = \
-      SelectValue<SelectedTag_##NAME, DEFAULT_VALUE>::value; \
-  }
-
-/// Defines a LogDomain with the given name and description.
-///
-/// The logger is default compile-time enabled depending on MATHICGB_LOG_##NAME
-/// (see MATHICGB_CAPTURE_LOG_ENABLED) and it is initially runtime
-/// enabled depending on the value of DEFAULT_RUNTIME_ENABLED. It is default
-/// runtime enabled for streaming (when also enabled in general) depending on
-/// DEFAULT_RUNTIME_STREAM_ENABLED.
-#define MATHICGB_DEFINE_LOG_DOMAIN_WITH_DEFAULTS( \
-  NAME, DESCRIPTION, \
-  DEFAULT_RUNTIME_ENABLED, \
-  DEFAULT_RUNTIME_STREAM_ENABLED, \
-  DEFAULT_COMPILE_TIME_ENABLED \
-) \
-  MATHICGB_CAPTURE_LOG_ENABLED(NAME, DEFAULT_COMPILE_TIME_ENABLED); \
-  namespace logs { \
-    typedef LogDomain< ::LogDomainInternal::value_##NAME> Type##NAME; \
-    Type##NAME NAME( \
-      #NAME, \
-      DESCRIPTION, \
-      DEFAULT_RUNTIME_ENABLED, \
-      DEFAULT_RUNTIME_STREAM_ENABLED \
-    ); \
-  }
-
-/// Defines a LogDomain with the given name and description.
-///
-/// The defaults for the logger are as follows.
-///       compile-time: enabled,
-///            runtime: disabled,
-///  runtime streaming: enabled (only takes effect if also enabled)
-#define MATHICGB_DEFINE_LOG_DOMAIN(NAME, DESCRIPTION) \
-  MATHICGB_DEFINE_LOG_DOMAIN_WITH_DEFAULTS(NAME, DESCRIPTION, 0, 1, 1);
-
-#define MATHICGB_DEFINE_LOG_ALIAS(ALIAS, OF) \
-  namespace LogDomainInternal { \
-    LogAliasRegisterer MATHICGB_CONCATENATE_AFTER_EXPANSION(reg_, __LINE__) \
-      (ALIAS, OF); \
-  }
-
-/// This expression yields an l-value reference to the indicated logger.
-///
-/// Example:
-///   auto timer = MATHICGB_LOGGER(MyDomain).timer();
-#define MATHICGB_LOGGER(DOMAIN) ::logs::DOMAIN
-
-/// This expression yields the type of the indicated logger.
-///
-/// Example:
-///   if (MATHICGB_LOGGER_TYPE(MyDomain)::compileTimeEnabled)
-///     std::ostream << "MyDomain is compiled time enabled";
-#define MATHICGB_LOGGER_TYPE(DOMAIN) ::logs::Type##DOMAIN
-
-/// Runs the code in the following scope delimited by braces {} if the
-/// indicated logger is enabled for streaming - otherwise does
-/// nothing.  Within the following scope there is a local reference
-/// variable log that refers to the indicated logger and a local
-/// reference variable stream that refers to log.stream().
-///
-/// Example:
-///   MATHICGB_IF_STREAM_LOG(MyDomain) {
-///     std::string msg;
-///     expensiveFunction(msg);
-///     stream << msg; // or log.stream() << msg;
-///   }
-#define MATHICGB_IF_STREAM_LOG(DOMAIN) \
-  if (MATHICGB_LOGGER(DOMAIN).streamEnabled()) \
-    LogDomainInternal::lambdaRunner(MATHICGB_LOGGER(DOMAIN)) + \
-      [&](MATHICGB_LOGGER_TYPE(DOMAIN)& log, std::ostream& stream)
-
-/// Display information to the log using <<.
-/// If domain is not enabled and stream enabled then the log message is not
-/// displayed and the code after << is not executed.
-///
-/// Example: (f() only called if logger is enabled)
-///   MATHICGB_LOG(domain) << "f() = " << f();
-#define MATHICGB_LOG(DOMAIN) \
-  if (MATHICGB_LOGGER(DOMAIN).streamEnabled()) MATHICGB_LOGGER(DOMAIN).stream()
-
-/// Will log the time to execute the remaining code in the current scope
-/// to the indicated domain. Also supports printing a message using <<.
-/// The message is printed right away while the time is printed when
-/// the scope ends.
-///
-/// Example:
-///   MATHICGB_LOG_SCOPE_TIME(MyDomain) << "Starting timed task";
-#define MATHICGB_LOG_TIME(DOMAIN) \
-  auto MATHICGB_CONCATENATE_AFTER_EXPANSION( \
-    DOMAIN, MATHICGB_CONCATENATE_AFTER_EXPANSION(_timer_, __LINE__)) \
-  (MATHICGB_LOGGER(DOMAIN).timer()); \
-  MATHICGB_LOG(DOMAIN)
-
-/// Increments the count of DOMAIN by the value of the expression BY. The
-/// expression BY is evaluated at most once and it is not evaluated if
-/// DOMAIN is disabled.
-///
-/// Example:
-///   MATHICGB_LOG_INCREMENT_BY(MyDomain, 3);
-#define MATHICGB_LOG_INCREMENT_BY(DOMAIN, BY) \
-  do { \
-    auto& MGBLOG_log = MATHICGB_LOGGER(DOMAIN); \
-    if (MGBLOG_log.enabled()) { \
-      MGBLOG_log.setCount(MGBLOG_log.count() + BY); \
-    } \
-  } while (false)
-
-/// Increments the count of DOMAIN by 1.
-#define MATHICGB_LOG_INCREMENT(DOMAIN) \
-  MATHICGB_LOG_INCREMENT_BY(DOMAIN, 1)
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_LOG_DOMAIN_GUARD
+#define MATHICGB_LOG_DOMAIN_GUARD
+
+#include "mtbb.hpp"
+#include <ostream>
+#include <ctime>
+#include <sstream>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// A named area of logging that can be turned on or off at runtime and at
+/// compile time.
+///
+/// A logger that is turned off at compile time emits no code
+/// into the executable and all the code that writes to that logger is also
+/// removed by the optimizer if it is written in the correct way. Use the
+/// logging macroes to ensure proper use so that compile-time disabled
+/// LogDomains properly have zero overhead. LogDomains can be turned on
+/// and off at compile time and at runtime individually.
+///
+/// Compile-time enabled loggers automatically register themselves at start-up
+/// with LogDomainSet::singleton().
+///
+/// @todo: support turning all loggers off globally with a macro, regardless
+/// of their individual compile-time on/off setting.
+
+template<bool CompileTimeEnabled>
+class LogDomain {};
+
+template<>
+class LogDomain<true> {
+public:
+  static const bool compileTimeEnabled = true;
+
+  LogDomain(
+    const char* const name,
+    const char* const description,
+    const bool enabled,
+    const bool streamEnabled
+  );
+
+  const char* name() const {return mName;}
+  const char* description() const {return mDescription;}
+  bool enabled() const {return mEnabled;}
+  bool streamEnabledPure() const {return mStreamEnabled;}
+  bool streamEnabled() const {return enabled() && streamEnabledPure();}
+
+  void setEnabled(const bool enabled) {mEnabled = enabled;}
+  void setStreamEnabled(const bool enabled) {mStreamEnabled = enabled;}
+
+  ::std::ostream& stream();
+
+  /// Class for recording time that is logged. Movable.
+  class Timer;
+
+  /// Returns a started timer.
+  Timer timer();
+
+  /// Returns true if any time has been logged on this logger, even if the
+  /// duration of that time was zero (that is., less than the resolution
+  /// of the timer).
+  bool hasTime() const {return mHasTime;}
+
+  double loggedSecondsReal() const;
+
+
+  typedef unsigned long long Counter;
+
+  Counter count() const {return mCount;}
+
+  void setCount(const Counter counter) {
+    if (enabled()) {
+      mCount = counter;
+      mHasCount = true;
+    }
+  }
+
+  /// Returns true if setCount has been called.
+  bool hasCount() const {return mHasCount;}
+
+  /// Resets this object to the state it had when it was
+  /// constructed.
+  void reset();
+
+private:
+  struct TimeInterval {
+    // todo: support user time too. clock() doesn't seem to sum the time
+    // for all threads, so that didn't work.
+    double realSeconds;
+
+    void print(::std::ostream& out) const;
+  };
+  void recordTime(TimeInterval interval);
+
+  bool mEnabled;
+  const bool mOriginallyEnabled;
+  bool mStreamEnabled;
+  const bool mOriginallyStreamEnabled;
+  const char* mName;
+  const char* mDescription;
+
+  TimeInterval mInterval; /// Total amount of time recorded on this log.
+  bool mHasTime; /// Whether any time has been registered (even if 0s).
+
+  Counter mCount;
+  bool mHasCount; /// Whether the count has been set (even if set to zero)
+};
+
+class LogDomain<true>::Timer {
+public:
+  /// Start the timer running. The elapsed time will be logged to the logger
+  /// once the timer is stopped or destructed.
+  Timer(LogDomain<true>& logger);
+
+  /// Stops the timer.
+  ~Timer();
+
+  /// Returns true if the timer is currently recording time.
+  bool running() const {return mTimerRunning;}
+
+  /// Stops recording time and logs the elapsed time to the logger.
+  ///
+  /// This is a no-op if the timer is not running. If the logger
+  /// is disabled then no time is logged.
+  void stop();
+
+  /// Start recording time on a stopped timer.
+  ///
+  /// This is a no-op if the timer is already running or if the logger is
+  /// disabled.
+  void start();
+
+private:
+  LogDomain<true>& mLogger;
+  bool mTimerRunning;
+  mgb::tbb::tick_count mRealTicks; // high precision
+};
+
+/// This is a compile-time disabled logger. You are not supposed to dynamically
+/// call any non-const methods on it other than the constructor. Code that
+/// calls other code will compile but it is an error if any of those
+/// methods get called at runtime.
+template<>
+class LogDomain<false> {
+public:
+  static const bool compileTimeEnabled = false;
+
+  LogDomain(const char* const, const char* const, const bool) {}
+
+  bool enabled() const {return false;}
+  bool streamEnabled() const {return false;}
+
+  class Timer {
+  public:
+    Timer(LogDomain<false>&) {}
+    bool running() const {return false;}
+    void stop() {MATHICGB_ASSERT(false);}
+    void start() {MATHICGB_ASSERT(false);}
+  };
+  Timer timer() {
+    MATHICGB_ASSERT(false);
+    return Timer(*this);
+  }
+
+  ::std::ostream& stream() {
+    MATHICGB_ASSERT(false);
+    return *static_cast< ::std::ostream*>(0);
+  }
+
+  typedef unsigned long long Counter;
+  Counter count() const {return 0;}
+  void setCount(const Counter counter) {MATHICGB_ASSERT(false);}
+  bool hasCount() const {return false;}
+  void reset() {}
+};
+
+namespace LogDomainInternal {
+  // Helpers for the logging macroes
+
+  template<class Tag, bool Default>
+  struct SelectValue {static const bool value = Default;};
+
+  template<class> struct Tag_ {};
+  template<class> struct Tag_0 {};
+  template<class> struct Tag_1 {};
+
+  template<bool Default>
+  struct SelectValue<Tag_0<int>, Default> {static const bool value = false;};
+
+  template<bool Default>
+  struct SelectValue<Tag_1<int>, Default> {static const bool value = true;};
+
+  template<class L>
+  struct LambdaRunner {L& log;};
+  template<class L>
+  LambdaRunner<L> lambdaRunner(L& l) {
+    LambdaRunner<L> r = {l};
+    return r;
+  }
+  template<class L, class T>
+  void operator+(LambdaRunner<L> runner, T&& lambda) {
+    lambda(runner.log, runner.log.stream());
+  }
+
+  struct LogAliasRegisterer {
+    LogAliasRegisterer(const char* alias, const char* of);
+  };
+}
+
+MATHICGB_NAMESPACE_END
+
+/// Defines LogDomainInternal::value_##NAME to be equal to the value of
+/// the macro MATHICGB_LOG_##NAME if that macro expands to 0 or 1. Otherwise
+/// the macro MATHICGB_LOG_##NAME is ignored and instead DEFAULT_VALUE is used.
+#define MATHICGB_CAPTURE_LOG_ENABLED(NAME, DEFAULT_VALUE) \
+  namespace mgb{namespace LogDomainInternal {             \
+    template<class> struct Tag_MATHICGB_LOG_##NAME {}; \
+    typedef MATHICGB_CONCATENATE_AFTER_EXPANSION(Tag_, MATHICGB_LOG_##NAME)<int> \
+      SelectedTag_##NAME; \
+    static const bool value_##NAME = \
+      SelectValue<SelectedTag_##NAME, DEFAULT_VALUE>::value; \
+  }}
+
+/// Defines a LogDomain with the given name and description.
+///
+/// The logger is default compile-time enabled depending on MATHICGB_LOG_##NAME
+/// (see MATHICGB_CAPTURE_LOG_ENABLED) and it is initially runtime
+/// enabled depending on the value of DEFAULT_RUNTIME_ENABLED. It is default
+/// runtime enabled for streaming (when also enabled in general) depending on
+/// DEFAULT_RUNTIME_STREAM_ENABLED.
+#define MATHICGB_DEFINE_LOG_DOMAIN_WITH_DEFAULTS( \
+  NAME, DESCRIPTION, \
+  DEFAULT_RUNTIME_ENABLED, \
+  DEFAULT_RUNTIME_STREAM_ENABLED, \
+  DEFAULT_COMPILE_TIME_ENABLED \
+) \
+  MATHICGB_CAPTURE_LOG_ENABLED(NAME, DEFAULT_COMPILE_TIME_ENABLED); \
+  namespace mgb{namespace logs {                                      \
+    typedef LogDomain< ::mgb::LogDomainInternal::value_##NAME> Type##NAME; \
+    Type##NAME NAME( \
+      #NAME, \
+      DESCRIPTION, \
+      DEFAULT_RUNTIME_ENABLED, \
+      DEFAULT_RUNTIME_STREAM_ENABLED \
+    ); \
+  }}
+
+/// Defines a LogDomain with the given name and description.
+///
+/// The defaults for the logger are as follows.
+///       compile-time: enabled,
+///            runtime: disabled,
+///  runtime streaming: enabled (only takes effect if also enabled)
+#define MATHICGB_DEFINE_LOG_DOMAIN(NAME, DESCRIPTION) \
+  MATHICGB_DEFINE_LOG_DOMAIN_WITH_DEFAULTS(NAME, DESCRIPTION, 0, 1, 1);
+
+#define MATHICGB_DEFINE_LOG_ALIAS(ALIAS, OF) \
+  namespace mgb{namespace LogDomainInternal {                           \
+    LogAliasRegisterer MATHICGB_CONCATENATE_AFTER_EXPANSION(reg_, __LINE__) \
+      (ALIAS, OF); \
+  }}
+
+/// This expression yields an l-value reference to the indicated logger.
+///
+/// Example:
+///   auto timer = MATHICGB_LOGGER(MyDomain).timer();
+#define MATHICGB_LOGGER(DOMAIN) ::mgb::logs::DOMAIN
+
+/// This expression yields the type of the indicated logger.
+///
+/// Example:
+///   if (MATHICGB_LOGGER_TYPE(MyDomain)::compileTimeEnabled)
+///     ::std::ostream << "MyDomain is compiled time enabled";
+#define MATHICGB_LOGGER_TYPE(DOMAIN) ::mgb::logs::Type##DOMAIN
+
+/// Runs the code in the following scope delimited by braces {} if the
+/// indicated logger is enabled for streaming - otherwise does
+/// nothing.  Within the following scope there is a local reference
+/// variable log that refers to the indicated logger and a local
+/// reference variable stream that refers to log.stream().
+///
+/// Example:
+///   MATHICGB_IF_STREAM_LOG(MyDomain) {
+///     ::std::string msg;
+///     expensiveFunction(msg);
+///     stream << msg; // or log.stream() << msg;
+///   }
+#define MATHICGB_IF_STREAM_LOG(DOMAIN) \
+  if (MATHICGB_LOGGER(DOMAIN).streamEnabled()) \
+    LogDomainInternal::lambdaRunner(MATHICGB_LOGGER(DOMAIN)) + \
+      [&](MATHICGB_LOGGER_TYPE(DOMAIN)& log, ::std::ostream& stream)
+
+/// Display information to the log using <<.
+/// If domain is not enabled and stream enabled then the log message is not
+/// displayed and the code after << is not executed.
+///
+/// Example: (f() only called if logger is enabled)
+///   MATHICGB_LOG(domain) << "f() = " << f();
+#define MATHICGB_LOG(DOMAIN) \
+  if (MATHICGB_LOGGER(DOMAIN).streamEnabled()) MATHICGB_LOGGER(DOMAIN).stream()
+
+/// Will log the time to execute the remaining code in the current scope
+/// to the indicated domain. Also supports printing a message using <<.
+/// The message is printed right away while the time is printed when
+/// the scope ends.
+///
+/// Example:
+///   MATHICGB_LOG_SCOPE_TIME(MyDomain) << "Starting timed task";
+#define MATHICGB_LOG_TIME(DOMAIN) \
+  auto MATHICGB_CONCATENATE_AFTER_EXPANSION( \
+    DOMAIN, MATHICGB_CONCATENATE_AFTER_EXPANSION(_timer_, __LINE__)) \
+  (MATHICGB_LOGGER(DOMAIN).timer()); \
+  MATHICGB_LOG(DOMAIN)
+
+/// Increments the count of DOMAIN by the value of the expression BY. The
+/// expression BY is evaluated at most once and it is not evaluated if
+/// DOMAIN is disabled.
+///
+/// Example:
+///   MATHICGB_LOG_INCREMENT_BY(MyDomain, 3);
+#define MATHICGB_LOG_INCREMENT_BY(DOMAIN, BY) \
+  do { \
+    auto& MGBLOG_log = MATHICGB_LOGGER(DOMAIN); \
+    if (MGBLOG_log.enabled()) { \
+      MGBLOG_log.setCount(MGBLOG_log.count() + BY); \
+    } \
+  } while (false)
+
+/// Increments the count of DOMAIN by 1.
+#define MATHICGB_LOG_INCREMENT(DOMAIN) \
+  MATHICGB_LOG_INCREMENT_BY(DOMAIN, 1)
+
+#endif
diff --git a/src/mathicgb/LogDomainSet.cpp b/src/mathicgb/LogDomainSet.cpp
index 7ced995..995a789 100755
--- a/src/mathicgb/LogDomainSet.cpp
+++ b/src/mathicgb/LogDomainSet.cpp
@@ -1,8 +1,12 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "LogDomainSet.hpp"
 
 #include <mathic.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 LogDomainSet::LogDomainSet():
   mStartTime(mgb::tbb::tick_count::now()) {
 }
@@ -208,3 +212,5 @@ LogDomainSet& LogDomainSet::singleton() {
   static LogDomainSet set;
   return set;
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/LogDomainSet.hpp b/src/mathicgb/LogDomainSet.hpp
index f73481b..cfa5ccd 100755
--- a/src/mathicgb/LogDomainSet.hpp
+++ b/src/mathicgb/LogDomainSet.hpp
@@ -1,90 +1,95 @@
-#ifndef MATHICGB_LOG_DOMAIN_SET_GUARD
-#define MATHICGB_LOG_DOMAIN_SET_GUARD
-
-#include "LogDomain.hpp"
-#include "mtbb.hpp"
-#include <string>
-#include <vector>
-#include <algorithm>
-#include <cstring>
-#include <ostream>
-
-class LogDomainSet {
-public:
-  void registerLogDomain(LogDomain<true>& domain);
-  void registerLogDomain(const LogDomain<false>& domain) {}
-
-  void registerLogAlias(const char* alias, const char* of);
-
-  /// A log command has the format AXB, where
-  ///   X       the name of a compile-time enabled log domain
-  ///   A       a prefix
-  ///   B       a suffix
-  /// The possible values of A are
-  ///           enable X (this is the empty string)
-  ///   +       enable X
-  ///   -       disable X
-  ///   0       do nothing
-  /// The possible values of B are
-  ///           do nothing (this is the empty string)
-  ///   +       stream-enabled X
-  ///   -       stream-disable X
-  ///   0       do nothing
-  ///
-  /// No white-space is allowed.
-  /// If the command cannot be parsed then you will get an exception.
-  ///
-  /// *** Example ***
-  /// Consider this sequence of commands:
-  ///   "+MyLog-" will enabled MyLog, but silence any streaming from it.
-  ///   "+MyLog" will make no difference, as MyLog is already enabled.
-  ///   "-MyLog+" will disable MyLog, but set the streaming state to enabled.
-  ///     As MyLog is disabled there will still be no streaming output.
-  ///   "+MyLog" will enabled MyLog. Since the streaming state was enabled
-  ///     before, we now get streaming.
-  ///
-  void performLogCommand(std::string cmd)
-    {performLogCommandInternal(' ', std::move(cmd), ' ');}
-
-  /// Performs a comma-seperated list of commands. No white-space is allowed.
-  void performLogCommands(const std::string& cmds)
-    {performLogCommandsInternal(' ', cmds, ' ');}
-
-  LogDomain<true>* logDomain(const char* const name);
-
-  const char* alias(const char* name);
-
-  const std::vector<LogDomain<true>*>& logDomains() const {return mLogDomains;}
-  const std::vector<std::pair<const char*, const char*>>& aliases() const
-    {return mAliases;}
-
-  void printReport(std::ostream& out) const;
-  void printTimeReport(std::ostream& out) const;
-  void printCountReport(std::ostream& out) const;
-
-  /// Resets the logging system as though the program had just started up.
-  /// This resets all counts, all recorded time and the enabledness of all logs.
-  /// You should not have a timer running for a log when you call this method.
-  void reset();
-
-  static LogDomainSet& singleton();
-
-private:
-  void performLogCommandInternal(
-    char prefix,
-    std::string name,
-    char suffix
-  );
-  void performLogCommandsInternal(
-    const char prefix,
-    const std::string& cmds,
-    const char suffix
-  );
-  LogDomainSet(); // private for singleton
-
-  std::vector<LogDomain<true>*> mLogDomains;
-  std::vector<std::pair<const char*, const char*>> mAliases;
-  mgb::tbb::tick_count mStartTime;
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_LOG_DOMAIN_SET_GUARD
+#define MATHICGB_LOG_DOMAIN_SET_GUARD
+
+#include "LogDomain.hpp"
+#include "mtbb.hpp"
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cstring>
+#include <ostream>
+
+MATHICGB_NAMESPACE_BEGIN
+
+class LogDomainSet {
+public:
+  void registerLogDomain(LogDomain<true>& domain);
+  void registerLogDomain(const LogDomain<false>& domain) {}
+
+  void registerLogAlias(const char* alias, const char* of);
+
+  /// A log command has the format AXB, where
+  ///   X       the name of a compile-time enabled log domain
+  ///   A       a prefix
+  ///   B       a suffix
+  /// The possible values of A are
+  ///           enable X (this is the empty string)
+  ///   +       enable X
+  ///   -       disable X
+  ///   0       do nothing
+  /// The possible values of B are
+  ///           do nothing (this is the empty string)
+  ///   +       stream-enabled X
+  ///   -       stream-disable X
+  ///   0       do nothing
+  ///
+  /// No white-space is allowed.
+  /// If the command cannot be parsed then you will get an exception.
+  ///
+  /// *** Example ***
+  /// Consider this sequence of commands:
+  ///   "+MyLog-" will enabled MyLog, but silence any streaming from it.
+  ///   "+MyLog" will make no difference, as MyLog is already enabled.
+  ///   "-MyLog+" will disable MyLog, but set the streaming state to enabled.
+  ///     As MyLog is disabled there will still be no streaming output.
+  ///   "+MyLog" will enabled MyLog. Since the streaming state was enabled
+  ///     before, we now get streaming.
+  ///
+  void performLogCommand(std::string cmd)
+    {performLogCommandInternal(' ', std::move(cmd), ' ');}
+
+  /// Performs a comma-seperated list of commands. No white-space is allowed.
+  void performLogCommands(const std::string& cmds)
+    {performLogCommandsInternal(' ', cmds, ' ');}
+
+  LogDomain<true>* logDomain(const char* const name);
+
+  const char* alias(const char* name);
+
+  const std::vector<LogDomain<true>*>& logDomains() const {return mLogDomains;}
+  const std::vector<std::pair<const char*, const char*>>& aliases() const
+    {return mAliases;}
+
+  void printReport(std::ostream& out) const;
+  void printTimeReport(std::ostream& out) const;
+  void printCountReport(std::ostream& out) const;
+
+  /// Resets the logging system as though the program had just started up.
+  /// This resets all counts, all recorded time and the enabledness of all logs.
+  /// You should not have a timer running for a log when you call this method.
+  void reset();
+
+  static LogDomainSet& singleton();
+
+private:
+  void performLogCommandInternal(
+    char prefix,
+    std::string name,
+    char suffix
+  );
+  void performLogCommandsInternal(
+    const char prefix,
+    const std::string& cmds,
+    const char suffix
+  );
+  LogDomainSet(); // private for singleton
+
+  std::vector<LogDomain<true>*> mLogDomains;
+  std::vector<std::pair<const char*, const char*>> mAliases;
+  mgb::tbb::tick_count mStartTime;
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/MTArray.cpp b/src/mathicgb/MTArray.cpp
index 53ff925..42bb736 100755
--- a/src/mathicgb/MTArray.cpp
+++ b/src/mathicgb/MTArray.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "MTArray.hpp"
 
@@ -5,6 +7,8 @@
 #include "MonTableKDTree.hpp"
 #include "MonTableDivList.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 template <typename MT>
 class MTArrayT : public MonomialTableArray
 {
@@ -254,7 +258,4 @@ std::unique_ptr<MonomialTableArray> MonomialTableArray::make(const PolyRing *R,
   }
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/MTArray.hpp b/src/mathicgb/MTArray.hpp
index 22a5573..28d84a1 100755
--- a/src/mathicgb/MTArray.hpp
+++ b/src/mathicgb/MTArray.hpp
@@ -1,13 +1,15 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _monomial_module_h_
-#define _monomial_module_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_M_T_ARRAY_GUARD
+#define MATHICGB_M_T_ARRAY_GUARD
 
 #include "PolyRing.hpp"
 #include <vector>
 #include <iostream>
 #include <algorithm>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class MonomialTableArray
 {
 public:
@@ -99,9 +101,5 @@ protected:
   const PolyRing *R;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/MathicIO.cpp b/src/mathicgb/MathicIO.cpp
index 2f0dd0d..ecd51fd 100755
--- a/src/mathicgb/MathicIO.cpp
+++ b/src/mathicgb/MathicIO.cpp
@@ -1,373 +1,379 @@
-#include "stdinc.h"
-#include "MathicIO.hpp"
-
-auto MathicIO::readBaseField(Scanner& in) -> BaseField {
-  return BaseField(in.readInteger<RawCoefficient>());
-}
-
-void MathicIO::writeBaseField(const BaseField& field, std::ostream& out) {
-  out << field.charac();
-}
-
-auto MathicIO::readRing(
-  const bool withComponent,
-  Scanner& in
-) -> std::pair<std::unique_ptr<PolyRing>, Processor> {
-  auto baseField = readBaseField(in);
-  const auto varCount = in.readInteger<VarIndex>();
-  auto order = readOrder(varCount, withComponent, in);
-  const bool componentsAscendingDesired = order.componentsAscendingDesired();
-  const bool schreyering = order.schreyering();
-  auto ring = make_unique<PolyRing>
-    (std::move(baseField), Monoid(std::move(order)));
-
-  Processor processor(ring->monoid(), componentsAscendingDesired, schreyering);
-
-  return std::make_pair(std::move(ring), std::move(processor));
-}
-
-void MathicIO::writeRing(
-  const PolyRing& ring,
-  const Processor& processor,
-  const bool withComponent,
-  std::ostream& out
-){
-  writeBaseField(ring.field(), out);
-  out << ' ' << ring.varCount() << '\n';
-
-  auto&& order = ring.monoid().makeOrder(
-    processor.componentsAscendingDesired(),
-    processor.schreyering()
-  );
-  writeOrder(order, withComponent, out);
-}
-
-auto MathicIO::readOrder(
-  const VarIndex varCount,
-  const bool withComponent,
-  Scanner& in
-) -> Order {
-  const bool schreyering = in.match("schreyer");
-  bool lexBaseOrder = !in.match("revlex") && in.match("lex");
-
-  const auto gradingCount = in.readInteger<VarIndex>();
-  bool componentsAscendingDesired = true;
-  auto componentCompareIndex = Order::ComponentAfterBaseOrder;
-  Gradings gradings(static_cast<size_t>(varCount) * gradingCount);
-  size_t index = 0;
-  for (VarIndex grading = 0; grading <  gradingCount; ++grading) {
-    const bool com = in.match("component");
-    if (com || in.match("revcomponent")) {
-      if (!withComponent)
-        in.reportError("Cannot specify component comparison for non-modules.");
-      MATHICGB_ASSERT(Monoid::HasComponent);
-      if (componentCompareIndex != Order::ComponentAfterBaseOrder)
-        in.reportError("Component comparison must be specified at most once.");
-      componentsAscendingDesired = com;
-      componentCompareIndex = grading;
-      index += varCount;
-    } else {
-      for (VarIndex i = 0; i < varCount; ++i, ++index)
-        gradings[index] = in.readInteger<Exponent>();
-    }
-  }
-  MATHICGB_ASSERT(index == gradings.size());
-
-  const bool moreLex = in.match("_lex");
-  if (moreLex || in.match("_revlex")) {
-    lexBaseOrder = moreLex;
-    const bool moreCom = in.match("component");
-    if (moreCom || in.match("revcomponent")) {
-      if (!withComponent)
-        in.reportError("Cannot specify component comparison for non-modules.");
-      MATHICGB_ASSERT(Monoid::HasComponent);
-      componentsAscendingDesired = moreCom;
-    }
-  }
-
-  Order order(
-    varCount,
-    std::move(gradings),
-    lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
-    componentCompareIndex,
-    componentsAscendingDesired,
-    schreyering
-  );
-  return std::move(order);
-}
-
-void MathicIO::writeOrder(
-  const Order& order,
-  const bool withComponent,
-  std::ostream& out
-) {
-  MATHICGB_ASSERT(Monoid::HasComponent || !withComponent);
-
-  const auto baseOrder =
-    order.baseOrder() == Order::LexBaseOrder ? "lex" : "revlex";
-  const auto componentOrder =
-    order.componentsAscendingDesired() ? "component" : "revcomponent";
-
-  if (order.schreyering())
-    out << "schreyer ";
-  out << baseOrder << ' ' << order.gradingCount() << '\n';
-  for (VarIndex grading = 0; grading < order.gradingCount(); ++grading) {
-    if (withComponent && grading == order.componentGradingIndex())
-      out << ' ' << componentOrder;
-    else {
-      for (VarIndex var = 0; var < order.varCount(); ++var) {
-        const auto index = var + grading * order.varCount();
-        out << ' ' << unchar(order.gradings()[index]);
-      }
-    }
-    out << '\n';
-  }
-  if (
-    withComponent &&
-    !order.componentsAscendingDesired() &&
-    order.componentGradingIndex() == Order::ComponentAfterBaseOrder
-  ) {
-    out << " _" << baseOrder << "\n " << componentOrder << '\n';
-  }
-}
-
-Basis MathicIO::readBasis(
-  const PolyRing& ring,
-  const bool readComponent,
-  Scanner& in
-) {
-  const auto polyCount = in.readInteger<size_t>();
-  Basis basis(ring);
-  for (size_t i = 0; i < polyCount; ++i) {
-    auto p = make_unique<Poly>(readPoly(ring, readComponent, in));
-    p->sortTermsDescending();
-    basis.insert(std::move(p));
-  }
-  return std::move(basis);
-}
-
-void MathicIO::writeBasis(
-  const Basis& basis,
-  const bool writeComponent,
-  std::ostream& out
-) {
-  out << basis.size() << '\n';
-  for (size_t i = 0; i < basis.size(); ++i) {
-    out << ' ';
-    writePoly(*basis.getPoly(i), writeComponent, out);
-    out << '\n';
-  }
-}
-
-Poly MathicIO::readPoly(
-  const PolyRing& ring,
-  const bool readComponent,
-  Scanner& in
-) {
-  Poly p(ring);
-
-  // also skips whitespace
-  if (in.match('0') || in.match("+0") || in.match("-0"))
-    return std::move(p);
-  MATHICGB_ASSERT(!in.peekWhite());
-
-  auto mono = ring.monoid().alloc();
-  auto coef = ring.field().zero();
-  do {
-    if (!p.isZero() && !in.peekSign())
-      in.expect('+', '-');
-    readTerm(ring, readComponent, coef, mono, in);
-    p.appendTerm(coef.value(), mono);
-  } while (!in.peekWhite() && !in.matchEOF());
-  return std::move(p);
-}
-
-void MathicIO::writePoly(
-  const Poly& poly,
-  const bool writeComponent,
-  std::ostream& out
-) {
-  if (poly.isZero()) {
-    out << '0';
-    return;
-  }
-
-  const auto end = poly.end();
-  for (auto it = poly.begin(); it != end; ++it) {
-    if (it != poly.begin())
-      out << '+';
-    writeTerm(
-      poly.ring(),
-      writeComponent,
-      poly.ring().field().toElement(it.getCoefficient()),
-      it.getMonomial(),
-      out
-    );
-  }
-}
-
-void MathicIO::readTerm(
-  const PolyRing& ring,
-  const bool readComponent,
-  Coefficient& coef,
-  MonoRef mono,
-  Scanner& in
-) {
-  // ** Read coefficient, if any.
-  const auto& field = ring.field();
-  const auto& monoid = ring.monoid();
-  const bool negate = !in.match('+') && in.match('-');
-  if (in.peekDigit()) {
-    coef = in.readModular(field, negate);
-
-    if (!in.peekAlpha()) {
-      // Identify a number c on its own as the monomial 1 times c.
-      monoid.setIdentity(mono);
-      if (readComponent)
-        this->readComponent(monoid, mono, in);
-      return;
-    }
-  } else if (negate)
-    coef = field.minusOne();
-  else
-    coef = field.one();
-
-  readMonomial(monoid, readComponent, mono, in);
-}
-
-void MathicIO::writeTerm(
-  const PolyRing& ring,
-  const bool writeComponent,
-  const Coefficient coef,
-  ConstMonoRef mono,
-  std::ostream& out
-) {
-  if (!ring.field().isOne(coef)) {
-    out << unchar(coef.value());
-    if (ring.monoid().isIdentity(mono)) {
-      if (writeComponent)
-        this->writeComponent(ring.monoid(), mono, out);
-      return;
-    }
-  } 
-  writeMonomial(ring.monoid(), writeComponent, mono, out);
-}
-
-void MathicIO::readMonomial(
-  const Monoid& monoid,
-  const bool readComponent,
-  MonoRef mono,
-  Scanner& in
-) {
-  MATHICGB_ASSERT(!readComponent || Monoid::HasComponent);
-
-  monoid.setIdentity(mono);
-  if (in.peek() == '1') {
-    const auto e = in.readInteger<Exponent>();
-    if (e != 1) {
-      std::ostringstream err;
-      err << "Expected monomial, but got " << e << " (did you mean 1?).";
-      in.reportError(err.str());
-    }
-  } else {
-    bool sawSome = false;
-    while (true) {
-      const auto letterCount = 'z' - 'a' + 1;
-      const auto letter = in.peek();
-      
-      VarIndex var;
-      if ('a' <= letter && letter <= 'z')
-        var = letter - 'a';
-      else if ('A' <= letter && letter <= 'Z')
-        var = (letter - 'A') + letterCount;
-      else if (sawSome)
-        break;
-      else {
-        std::ostringstream err;
-        err << "Expected letter while reading monomial, but got '"
-          << static_cast<char>(letter) << "'.";
-        in.reportError(err.str());
-        return;
-      }
-      in.get(); // skip past letter
-      
-      MATHICGB_ASSERT(var < 2 * letterCount);
-      if (var >= monoid.varCount()) {
-        std::ostringstream err;
-        err << "Saw the variable " << static_cast<char>(letter)
-          << ", but the monoid only has "
-          << monoid.varCount() << " variables.";
-        in.reportError(err.str());
-        return;
-      }
-      if (monoid.exponent(mono, var) > static_cast<Exponent>(0)) {
-        std::ostringstream err;
-        err << "Variable " << static_cast<char>(letter) <<
-          " must not be written twice in one monomial.";
-        in.reportError(err.str());
-      }
-      
-      if (in.peekDigit())
-        monoid.setExponent(var, in.readInteger<Exponent>(), mono);
-      else
-        monoid.setExponent(var, static_cast<Exponent>(1), mono);
-      sawSome = true;
-    }
-  }
-
-  if (readComponent)
-    this->readComponent(monoid, mono, in);
-}
-
-void MathicIO::readComponent(
-  const Monoid& monoid,
-  MonoRef mono,
-  Scanner& in
-) {
-  MATHICGB_ASSERT(Monoid::HasComponent);
-  in.expect('<');
-  monoid.setComponent(in.readInteger<Exponent>(), mono);
-  in.expect('>');
-}
-
-void MathicIO::writeComponent(
-  const Monoid& monoid,
-  ConstMonoRef mono,
-  std::ostream& out
-) {
-  MATHICGB_ASSERT(Monoid::HasComponent);
-  out << '<' << unchar(monoid.component(mono)) << '>';
-}
-
-/// Print a monomial with no coefficient.
-void MathicIO::writeMonomial(
-  const Monoid& monoid,
-  const bool writeComponent,
-  ConstMonoRef mono,
-  std::ostream& out
-) {
-  const auto letterCount = 'z' - 'a' + 1;
-
-  bool printedSome = false;
-  for (VarIndex var = 0; var < monoid.varCount(); ++var) {
-    if (monoid.exponent(mono, var) == 0)
-      continue;
-    char letter;
-    if (var < letterCount)
-      letter = 'a' + static_cast<char>(var);
-    else if (var < 2 * letterCount)
-      letter = 'A' + (static_cast<char>(var) - letterCount);
-    else {
-      mathic::reportError("Too few letters in alphabet to print variable.");
-      return;
-    }
-    printedSome = true;
-    out << letter;
-    if (monoid.exponent(mono, var) != 1)
-      out << unchar(monoid.exponent(mono, var));
-  }
-  if (!printedSome)
-    out << '1';
-  if (writeComponent)
-    this->writeComponent(monoid, mono, out);
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "stdinc.h"
+#include "MathicIO.hpp"
+
+MATHICGB_NAMESPACE_BEGIN
+
+auto MathicIO::readBaseField(Scanner& in) -> BaseField {
+  return BaseField(in.readInteger<RawCoefficient>());
+}
+
+void MathicIO::writeBaseField(const BaseField& field, std::ostream& out) {
+  out << field.charac();
+}
+
+auto MathicIO::readRing(
+  const bool withComponent,
+  Scanner& in
+) -> std::pair<std::unique_ptr<PolyRing>, Processor> {
+  auto baseField = readBaseField(in);
+  const auto varCount = in.readInteger<VarIndex>();
+  auto order = readOrder(varCount, withComponent, in);
+  const bool componentsAscendingDesired = order.componentsAscendingDesired();
+  const bool schreyering = order.schreyering();
+  auto ring = make_unique<PolyRing>
+    (std::move(baseField), Monoid(std::move(order)));
+
+  Processor processor(ring->monoid(), componentsAscendingDesired, schreyering);
+
+  return std::make_pair(std::move(ring), std::move(processor));
+}
+
+void MathicIO::writeRing(
+  const PolyRing& ring,
+  const Processor& processor,
+  const bool withComponent,
+  std::ostream& out
+){
+  writeBaseField(ring.field(), out);
+  out << ' ' << ring.varCount() << '\n';
+
+  auto&& order = ring.monoid().makeOrder(
+    processor.componentsAscendingDesired(),
+    processor.schreyering()
+  );
+  writeOrder(order, withComponent, out);
+}
+
+auto MathicIO::readOrder(
+  const VarIndex varCount,
+  const bool withComponent,
+  Scanner& in
+) -> Order {
+  const bool schreyering = in.match("schreyer");
+  bool lexBaseOrder = !in.match("revlex") && in.match("lex");
+
+  const auto gradingCount = in.readInteger<VarIndex>();
+  bool componentsAscendingDesired = true;
+  auto componentCompareIndex = Order::ComponentAfterBaseOrder;
+  Gradings gradings(static_cast<size_t>(varCount) * gradingCount);
+  size_t index = 0;
+  for (VarIndex grading = 0; grading <  gradingCount; ++grading) {
+    const bool com = in.match("component");
+    if (com || in.match("revcomponent")) {
+      if (!withComponent)
+        in.reportError("Cannot specify component comparison for non-modules.");
+      MATHICGB_ASSERT(Monoid::HasComponent);
+      if (componentCompareIndex != Order::ComponentAfterBaseOrder)
+        in.reportError("Component comparison must be specified at most once.");
+      componentsAscendingDesired = com;
+      componentCompareIndex = grading;
+      index += varCount;
+    } else {
+      for (VarIndex i = 0; i < varCount; ++i, ++index)
+        gradings[index] = in.readInteger<Exponent>();
+    }
+  }
+  MATHICGB_ASSERT(index == gradings.size());
+
+  const bool moreLex = in.match("_lex");
+  if (moreLex || in.match("_revlex")) {
+    lexBaseOrder = moreLex;
+    const bool moreCom = in.match("component");
+    if (moreCom || in.match("revcomponent")) {
+      if (!withComponent)
+        in.reportError("Cannot specify component comparison for non-modules.");
+      MATHICGB_ASSERT(Monoid::HasComponent);
+      componentsAscendingDesired = moreCom;
+    }
+  }
+
+  Order order(
+    varCount,
+    std::move(gradings),
+    lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+    componentCompareIndex,
+    componentsAscendingDesired,
+    schreyering
+  );
+  return std::move(order);
+}
+
+void MathicIO::writeOrder(
+  const Order& order,
+  const bool withComponent,
+  std::ostream& out
+) {
+  MATHICGB_ASSERT(Monoid::HasComponent || !withComponent);
+
+  const auto baseOrder =
+    order.baseOrder() == Order::LexBaseOrder ? "lex" : "revlex";
+  const auto componentOrder =
+    order.componentsAscendingDesired() ? "component" : "revcomponent";
+
+  if (order.schreyering())
+    out << "schreyer ";
+  out << baseOrder << ' ' << order.gradingCount() << '\n';
+  for (VarIndex grading = 0; grading < order.gradingCount(); ++grading) {
+    if (withComponent && grading == order.componentGradingIndex())
+      out << ' ' << componentOrder;
+    else {
+      for (VarIndex var = 0; var < order.varCount(); ++var) {
+        const auto index = var + grading * order.varCount();
+        out << ' ' << unchar(order.gradings()[index]);
+      }
+    }
+    out << '\n';
+  }
+  if (
+    withComponent &&
+    !order.componentsAscendingDesired() &&
+    order.componentGradingIndex() == Order::ComponentAfterBaseOrder
+  ) {
+    out << " _" << baseOrder << "\n " << componentOrder << '\n';
+  }
+}
+
+Basis MathicIO::readBasis(
+  const PolyRing& ring,
+  const bool readComponent,
+  Scanner& in
+) {
+  const auto polyCount = in.readInteger<size_t>();
+  Basis basis(ring);
+  for (size_t i = 0; i < polyCount; ++i) {
+    auto p = make_unique<Poly>(readPoly(ring, readComponent, in));
+    p->sortTermsDescending();
+    basis.insert(std::move(p));
+  }
+  return std::move(basis);
+}
+
+void MathicIO::writeBasis(
+  const Basis& basis,
+  const bool writeComponent,
+  std::ostream& out
+) {
+  out << basis.size() << '\n';
+  for (size_t i = 0; i < basis.size(); ++i) {
+    out << ' ';
+    writePoly(*basis.getPoly(i), writeComponent, out);
+    out << '\n';
+  }
+}
+
+Poly MathicIO::readPoly(
+  const PolyRing& ring,
+  const bool readComponent,
+  Scanner& in
+) {
+  Poly p(ring);
+
+  // also skips whitespace
+  if (in.match('0') || in.match("+0") || in.match("-0"))
+    return std::move(p);
+  MATHICGB_ASSERT(!in.peekWhite());
+
+  auto mono = ring.monoid().alloc();
+  auto coef = ring.field().zero();
+  do {
+    if (!p.isZero() && !in.peekSign())
+      in.expect('+', '-');
+    readTerm(ring, readComponent, coef, mono, in);
+    p.appendTerm(coef.value(), mono);
+  } while (!in.peekWhite() && !in.matchEOF());
+  return std::move(p);
+}
+
+void MathicIO::writePoly(
+  const Poly& poly,
+  const bool writeComponent,
+  std::ostream& out
+) {
+  if (poly.isZero()) {
+    out << '0';
+    return;
+  }
+
+  const auto end = poly.end();
+  for (auto it = poly.begin(); it != end; ++it) {
+    if (it != poly.begin())
+      out << '+';
+    writeTerm(
+      poly.ring(),
+      writeComponent,
+      poly.ring().field().toElement(it.getCoefficient()),
+      it.getMonomial(),
+      out
+    );
+  }
+}
+
+void MathicIO::readTerm(
+  const PolyRing& ring,
+  const bool readComponent,
+  Coefficient& coef,
+  MonoRef mono,
+  Scanner& in
+) {
+  // ** Read coefficient, if any.
+  const auto& field = ring.field();
+  const auto& monoid = ring.monoid();
+  const bool negate = !in.match('+') && in.match('-');
+  if (in.peekDigit()) {
+    coef = in.readModular(field, negate);
+
+    if (!in.peekAlpha()) {
+      // Identify a number c on its own as the monomial 1 times c.
+      monoid.setIdentity(mono);
+      if (readComponent)
+        this->readComponent(monoid, mono, in);
+      return;
+    }
+  } else if (negate)
+    coef = field.minusOne();
+  else
+    coef = field.one();
+
+  readMonomial(monoid, readComponent, mono, in);
+}
+
+void MathicIO::writeTerm(
+  const PolyRing& ring,
+  const bool writeComponent,
+  const Coefficient coef,
+  ConstMonoRef mono,
+  std::ostream& out
+) {
+  if (!ring.field().isOne(coef)) {
+    out << unchar(coef.value());
+    if (ring.monoid().isIdentity(mono)) {
+      if (writeComponent)
+        this->writeComponent(ring.monoid(), mono, out);
+      return;
+    }
+  } 
+  writeMonomial(ring.monoid(), writeComponent, mono, out);
+}
+
+void MathicIO::readMonomial(
+  const Monoid& monoid,
+  const bool readComponent,
+  MonoRef mono,
+  Scanner& in
+) {
+  MATHICGB_ASSERT(!readComponent || Monoid::HasComponent);
+
+  monoid.setIdentity(mono);
+  if (in.peek() == '1') {
+    const auto e = in.readInteger<Exponent>();
+    if (e != 1) {
+      std::ostringstream err;
+      err << "Expected monomial, but got " << e << " (did you mean 1?).";
+      in.reportError(err.str());
+    }
+  } else {
+    bool sawSome = false;
+    while (true) {
+      const auto letterCount = 'z' - 'a' + 1;
+      const auto letter = in.peek();
+      
+      VarIndex var;
+      if ('a' <= letter && letter <= 'z')
+        var = letter - 'a';
+      else if ('A' <= letter && letter <= 'Z')
+        var = (letter - 'A') + letterCount;
+      else if (sawSome)
+        break;
+      else {
+        std::ostringstream err;
+        err << "Expected letter while reading monomial, but got '"
+          << static_cast<char>(letter) << "'.";
+        in.reportError(err.str());
+        return;
+      }
+      in.get(); // skip past letter
+      
+      MATHICGB_ASSERT(var < 2 * letterCount);
+      if (var >= monoid.varCount()) {
+        std::ostringstream err;
+        err << "Saw the variable " << static_cast<char>(letter)
+          << ", but the monoid only has "
+          << monoid.varCount() << " variables.";
+        in.reportError(err.str());
+        return;
+      }
+      if (monoid.exponent(mono, var) > static_cast<Exponent>(0)) {
+        std::ostringstream err;
+        err << "Variable " << static_cast<char>(letter) <<
+          " must not be written twice in one monomial.";
+        in.reportError(err.str());
+      }
+      
+      if (in.peekDigit())
+        monoid.setExponent(var, in.readInteger<Exponent>(), mono);
+      else
+        monoid.setExponent(var, static_cast<Exponent>(1), mono);
+      sawSome = true;
+    }
+  }
+
+  if (readComponent)
+    this->readComponent(monoid, mono, in);
+}
+
+void MathicIO::readComponent(
+  const Monoid& monoid,
+  MonoRef mono,
+  Scanner& in
+) {
+  MATHICGB_ASSERT(Monoid::HasComponent);
+  in.expect('<');
+  monoid.setComponent(in.readInteger<Exponent>(), mono);
+  in.expect('>');
+}
+
+void MathicIO::writeComponent(
+  const Monoid& monoid,
+  ConstMonoRef mono,
+  std::ostream& out
+) {
+  MATHICGB_ASSERT(Monoid::HasComponent);
+  out << '<' << unchar(monoid.component(mono)) << '>';
+}
+
+/// Print a monomial with no coefficient.
+void MathicIO::writeMonomial(
+  const Monoid& monoid,
+  const bool writeComponent,
+  ConstMonoRef mono,
+  std::ostream& out
+) {
+  const auto letterCount = 'z' - 'a' + 1;
+
+  bool printedSome = false;
+  for (VarIndex var = 0; var < monoid.varCount(); ++var) {
+    if (monoid.exponent(mono, var) == 0)
+      continue;
+    char letter;
+    if (var < letterCount)
+      letter = 'a' + static_cast<char>(var);
+    else if (var < 2 * letterCount)
+      letter = 'A' + (static_cast<char>(var) - letterCount);
+    else {
+      mathic::reportError("Too few letters in alphabet to print variable.");
+      return;
+    }
+    printedSome = true;
+    out << letter;
+    if (monoid.exponent(mono, var) != 1)
+      out << unchar(monoid.exponent(mono, var));
+  }
+  if (!printedSome)
+    out << '1';
+  if (writeComponent)
+    this->writeComponent(monoid, mono, out);
+}
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/MathicIO.hpp b/src/mathicgb/MathicIO.hpp
index 6352ec3..9a3a75b 100755
--- a/src/mathicgb/MathicIO.hpp
+++ b/src/mathicgb/MathicIO.hpp
@@ -1,141 +1,146 @@
-#ifndef MATHICGB_MATHIC_IO_GUARD
-#define MATHICGB_MATHIC_IO_GUARD
-
-#include "Basis.hpp"
-#include "Poly.hpp"
-#include "Scanner.hpp"
-#include "PolyRing.hpp"
-#include "MonoProcessor.hpp"
-#include <ostream>
-#include <string>
-
-/// Class for input and output in Mathic's format.
-class MathicIO {
-public:
-  typedef PolyRing::Field BaseField;
-  typedef BaseField::Element Coefficient;
-  typedef BaseField::RawElement RawCoefficient;
-
-  typedef PolyRing::Monoid Monoid;
-  typedef Monoid::MonoRef MonoRef;
-  typedef Monoid::Exponent Exponent;
-  typedef Monoid::VarIndex VarIndex;
-  typedef Monoid::ConstMonoRef ConstMonoRef;
-  typedef Monoid::Order Order;
-  typedef MonoProcessor<Monoid> Processor;
-
-  typedef Order::Gradings Gradings;
-
-/*
-  /// reads ring, #gens, each generator in turn
-  typedef std::tuple<
-    std::unique_ptr<PolyRing>,
-    std::unique_ptr<Basis>,
-    std::unique_ptr<MonoProcessor<PolyRing::Monoid>>
-  > BasisData;
-  BasisData readBasis();
-
-
-
-*/
-  BaseField readBaseField(Scanner& in);
-  void writeBaseField(const BaseField& field, std::ostream& out);
-
-  std::pair<std::unique_ptr<PolyRing>, Processor> readRing(
-    const bool withComponent,
-    Scanner& in
-  );
-  void writeRing(
-    const PolyRing& ring,
-    const Processor& processor,
-    const bool withComponent,
-    std::ostream& out
-  );
-
-  Order readOrder(
-    const VarIndex varCount,
-    const bool withComponent,
-    Scanner& in
-  );
-
-  void writeOrder(
-    const Order& order,
-    const bool withComponent,
-    std::ostream& out
-  );
-
-  Basis readBasis(
-    const PolyRing& ring,
-    const bool readComponent,
-    Scanner& in
-  );
-
-  void writeBasis(
-    const Basis& basis,
-    const bool writeComponent,
-    std::ostream& out
-  );
-
-  Poly readPoly(
-    const PolyRing& ring,
-    const bool readComponent,
-    Scanner& in
-  );
-
-  void writePoly(
-    const Poly& poly,
-    const bool writeComponent,
-    std::ostream& out
-  );
-
-  void readTerm(
-    const PolyRing& ring,
-    const bool readComponent,
-    Coefficient& coef,
-    MonoRef mono,
-    Scanner& in
-  );
-
-  void writeTerm(
-    const PolyRing& ring,
-    const bool writeComponent,
-    const Coefficient coef,
-    ConstMonoRef mono,
-    std::ostream& out
-  );
-
-  /// Read a monomial with no coefficient. A 1 on its own is not
-  /// considered a coefficient here - it is the monomial with all
-  /// exponents zero and no coefficient.
-  ///
-  /// @todo: Eventually, pick up readComponent from Monoid::HasComponent.
-  void readMonomial(
-    const Monoid& monoid,
-    const bool readComponent,
-    MonoRef mono,
-    Scanner& in
-  );
-
-  /// Print a monomial with no coefficient.
-  void writeMonomial(
-    const Monoid& monoid,
-    const bool writeComponent,
-    ConstMonoRef mono,
-    std::ostream& out
-  );
-
-  /// Read the trailing indicator of the component of a module monomial.
-  void readComponent(
-    const Monoid& monoid,
-    MonoRef mono,
-    Scanner& in
-  );
-
-  void writeComponent(
-    const Monoid& monoid,
-    ConstMonoRef mono,
-    std::ostream& out
-  );
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_MATHIC_IO_GUARD
+#define MATHICGB_MATHIC_IO_GUARD
+
+#include "Basis.hpp"
+#include "Poly.hpp"
+#include "Scanner.hpp"
+#include "PolyRing.hpp"
+#include "MonoProcessor.hpp"
+#include <ostream>
+#include <string>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// Class for input and output in Mathic's format.
+class MathicIO {
+public:
+  typedef PolyRing::Field BaseField;
+  typedef BaseField::Element Coefficient;
+  typedef BaseField::RawElement RawCoefficient;
+
+  typedef PolyRing::Monoid Monoid;
+  typedef Monoid::MonoRef MonoRef;
+  typedef Monoid::Exponent Exponent;
+  typedef Monoid::VarIndex VarIndex;
+  typedef Monoid::ConstMonoRef ConstMonoRef;
+  typedef Monoid::Order Order;
+  typedef MonoProcessor<Monoid> Processor;
+
+  typedef Order::Gradings Gradings;
+
+/*
+  /// reads ring, #gens, each generator in turn
+  typedef std::tuple<
+    std::unique_ptr<PolyRing>,
+    std::unique_ptr<Basis>,
+    std::unique_ptr<MonoProcessor<PolyRing::Monoid>>
+  > BasisData;
+  BasisData readBasis();
+
+
+
+*/
+  BaseField readBaseField(Scanner& in);
+  void writeBaseField(const BaseField& field, std::ostream& out);
+
+  std::pair<std::unique_ptr<PolyRing>, Processor> readRing(
+    const bool withComponent,
+    Scanner& in
+  );
+  void writeRing(
+    const PolyRing& ring,
+    const Processor& processor,
+    const bool withComponent,
+    std::ostream& out
+  );
+
+  Order readOrder(
+    const VarIndex varCount,
+    const bool withComponent,
+    Scanner& in
+  );
+
+  void writeOrder(
+    const Order& order,
+    const bool withComponent,
+    std::ostream& out
+  );
+
+  Basis readBasis(
+    const PolyRing& ring,
+    const bool readComponent,
+    Scanner& in
+  );
+
+  void writeBasis(
+    const Basis& basis,
+    const bool writeComponent,
+    std::ostream& out
+  );
+
+  Poly readPoly(
+    const PolyRing& ring,
+    const bool readComponent,
+    Scanner& in
+  );
+
+  void writePoly(
+    const Poly& poly,
+    const bool writeComponent,
+    std::ostream& out
+  );
+
+  void readTerm(
+    const PolyRing& ring,
+    const bool readComponent,
+    Coefficient& coef,
+    MonoRef mono,
+    Scanner& in
+  );
+
+  void writeTerm(
+    const PolyRing& ring,
+    const bool writeComponent,
+    const Coefficient coef,
+    ConstMonoRef mono,
+    std::ostream& out
+  );
+
+  /// Read a monomial with no coefficient. A 1 on its own is not
+  /// considered a coefficient here - it is the monomial with all
+  /// exponents zero and no coefficient.
+  ///
+  /// @todo: Eventually, pick up readComponent from Monoid::HasComponent.
+  void readMonomial(
+    const Monoid& monoid,
+    const bool readComponent,
+    MonoRef mono,
+    Scanner& in
+  );
+
+  /// Print a monomial with no coefficient.
+  void writeMonomial(
+    const Monoid& monoid,
+    const bool writeComponent,
+    ConstMonoRef mono,
+    std::ostream& out
+  );
+
+  /// Read the trailing indicator of the component of a module monomial.
+  void readComponent(
+    const Monoid& monoid,
+    MonoRef mono,
+    Scanner& in
+  );
+
+  void writeComponent(
+    const Monoid& monoid,
+    ConstMonoRef mono,
+    std::ostream& out
+  );
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/MonTableDivList.hpp b/src/mathicgb/MonTableDivList.hpp
old mode 100644
new mode 100755
index 5e94d5c..d8e4220
--- a/src/mathicgb/MonTableDivList.hpp
+++ b/src/mathicgb/MonTableDivList.hpp
@@ -1,12 +1,15 @@
-#ifndef DIV_ARRAY_MODEL_GUARD
-#define DIV_ARRAY_MODEL_GUARD
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_MON_TABLE_DIV_LIST_GUARD
+#define MATHICGB_MON_TABLE_DIV_LIST_GUARD
 
+#include "PolyRing.hpp"
 #include <string>
 #include <vector>
 #include <iostream>
-
 #include <mathic.h>
-#include "PolyRing.hpp"
+
+MATHICGB_NAMESPACE_BEGIN
 
 /** Helper class for MonTableDivList. */
 template<bool UseLinkedList, bool UseDivMask>
@@ -279,9 +282,5 @@ void MonTableDivList<UDL, UDM>::getMonomials(std::vector<const_monomial>& monomi
   monomials.insert(monomials.begin(), begin(), end());
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/MonTableKDTree.hpp b/src/mathicgb/MonTableKDTree.hpp
index ddc8372..32da9da 100755
--- a/src/mathicgb/MonTableKDTree.hpp
+++ b/src/mathicgb/MonTableKDTree.hpp
@@ -1,13 +1,16 @@
-#ifndef K_D_TREE_MODEL_GUARD
-#define K_D_TREE_MODEL_GUARD
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_MON_TABLE_K_D_TREE_GUARD
+#define MATHICGB_MON_TABLE_K_D_TREE_GUARD
 
+#include "PolyRing.hpp"
 #include <string>
 #include <vector>
 #include <iostream>
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "PolyRing.hpp"
+MATHICGB_NAMESPACE_BEGIN
 
 /** Helper class for KDTreeModel. */
 template<bool UseDivMask, bool UseTreeDivMask, size_t LeafSize, bool AllowRemovals>
@@ -284,9 +287,5 @@ void MonTableKDTree<UDM, UTM, LS, AR>::getMonomials(std::vector<const_monomial>&
   _finder.forAll(copier);
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/MonTableNaive.cpp b/src/mathicgb/MonTableNaive.cpp
old mode 100644
new mode 100755
index 3543ec1..35a90dd
--- a/src/mathicgb/MonTableNaive.cpp
+++ b/src/mathicgb/MonTableNaive.cpp
@@ -1,10 +1,13 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
-#include <ostream>
 #include "MonTableNaive.hpp"
+
+#include <ostream>
 #include <iostream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 MonTableNaive::MonTableNaive(const PolyRing *R) :
   conf_(R),
   mPool(sizeof(mon_node)),
@@ -163,7 +166,4 @@ size_t MonTableNaive::getMemoryUse() const
   return mPool.getMemoryUse();
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/MonTableNaive.hpp b/src/mathicgb/MonTableNaive.hpp
old mode 100644
new mode 100755
index 4d135a5..f570401
--- a/src/mathicgb/MonTableNaive.hpp
+++ b/src/mathicgb/MonTableNaive.hpp
@@ -1,10 +1,12 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_MON_TABLE_NAIVE_GUARD
+#define MATHICGB_MON_TABLE_NAIVE_GUARD
 
-#ifndef _monomial_table_h_
-#define _monomial_table_h_
-
-#include <memtailor.h>
 #include "PolyRing.hpp"
+#include <memtailor.h>
+
+MATHICGB_NAMESPACE_BEGIN
 
 struct mon_node { // each node is in 'nodes' arena
   mon_node *next;
@@ -75,10 +77,5 @@ private:
   mutable Stats stats_;
 };
 
-
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/MonoMonoid.hpp b/src/mathicgb/MonoMonoid.hpp
index c81b60a..a94ed25 100755
--- a/src/mathicgb/MonoMonoid.hpp
+++ b/src/mathicgb/MonoMonoid.hpp
@@ -1,2009 +1,2014 @@
-#ifndef MATHICGB_MONO_MONOID_GUARD
-#define MATHICGB_MONO_MONOID_GUARD
-
-#include "MonoOrder.hpp"
-#include "NonCopyable.hpp"
-#include <vector>
-#include <algorithm>
-#include <memtailor.h>
-#include <type_traits>
-#include <istream>
-#include <utility>
-#include <ostream>
-#include <cstdlib>
-#include <cstring>
-#include <mathic.h>
-
-/// Implements the monoid of (monic) monomials with integer
-/// non-negative exponents. Exponent must be an unsigned integer type that is
-/// used to store each exponent of a monomial.
-template<
-  class Exponent,
-  bool HasComponent = true,
-  bool StoreHash = true,
-  bool StoreOrder = true
->
-class MonoMonoid;
-
-namespace MonoMonoidInternal {
-  template<class E, bool HC, bool SH, bool SO>
-  class Base {
-  public:
-    static const bool HasComponent = HC;
-    static const bool StoreHash = SH;
-    static const bool StoreOrder = SO;
-
-    typedef size_t VarIndex;
-    typedef E Exponent;
-    typedef typename std::make_unsigned<E>::type Component;
-    typedef typename std::make_unsigned<E>::type HashValue;
-    typedef const Exponent* const_iterator;
-    typedef MonoOrder<Exponent> Order;
-
-    Base(const Order& order):
-      mVarCount(order.varCount()),
-      mGradingCount(order.gradingCount()),
-      mOrderIndexBegin(HasComponent + order.varCount()),
-      mOrderIndexEnd(mOrderIndexBegin + StoreOrder * order.gradingCount()),
-      mEntryCount(std::max<VarIndex>(mOrderIndexEnd + StoreHash, 1)),
-      mHashCoefficients(makeHashCoefficients(order.varCount())),
-      mOrderIsTotalDegreeRevLex
-        (order.baseOrder() == Order::RevLexBaseOrder && order.isTotalDegree()),
-      mLexBaseOrder(order.baseOrder() == Order::LexBaseOrder),
-      mGradings(makeGradings(order)),
-      mComponentGradingIndex(
-        reverseComponentGradingIndex
-          (order.gradingCount(), order.componentGradingIndex())
-      )
-    {
-    }
-
-    VarIndex varCount() const {return mVarCount;}
-    VarIndex gradingCount() const {return mGradingCount;}
-
-    VarIndex entryCount() const {return mEntryCount;}
-    VarIndex orderIndexEnd() const {return mOrderIndexEnd;}
-    VarIndex orderIndexBegin() const {return mOrderIndexBegin;}
-    VarIndex hashIndex() const {return mOrderIndexEnd;}
-    VarIndex componentGradingIndex() const {return mComponentGradingIndex;}
-
-  protected:
-    typedef std::vector<Exponent> HashCoefficients;
-    typedef std::vector<Exponent> Gradings;
-
-    static Gradings makeGradings(const Order& order) {
-      auto gradings = order.gradings();
-      reverseGradings(order.varCount(), gradings);
-      if (order.baseOrder() == Order::RevLexBaseOrder)
-        negateGradings(gradings);
-      return gradings;
-    }
-
-    /// Reverse the relative order among the gradings - the first one
-    /// becomes the last one, the second first becomes the second last
-    /// and so on.
-    static void reverseGradings(const VarIndex varCount, Gradings& gradings) {
-      if (varCount == 0)
-        return;
-      MATHICGB_ASSERT(gradings.size() % varCount == 0);
-      const auto gradingCount = gradings.size() / varCount;
-
-      for (VarIndex grading = 0; grading < gradingCount / 2; ++grading) {
-        for (VarIndex var = 0; var < varCount; ++var) {
-          const auto index = gradingsIndex(grading, var, varCount);
-          const auto oppositeIndex = gradingsOppositeRowIndex
-            (grading, gradingCount, var, varCount);
-          std::swap(gradings[index], gradings[oppositeIndex]);
-        }
-      }
-    }
-
-    /// Replace each entry in the grading matrix with its negative.
-    static void negateGradings(Gradings& gradings) {
-      const auto size = gradings.size();
-      for (size_t i = 0; i < size; ++i)
-        gradings[i] = -gradings[i];
-    }
-
-    /// Since comparisons go opposite direction, we need to reverse
-    /// the component grading index, unless it's the special value
-    /// indicating that it goes last.
-    static VarIndex reverseComponentGradingIndex(
-      const VarIndex gradingCount,
-      const VarIndex componentGradingIndex
-    ) {
-      if (componentGradingIndex == Order::ComponentAfterBaseOrder)
-        return Order::ComponentAfterBaseOrder;
-      else
-        return gradingCount - 1 - componentGradingIndex;
-    }
-
-    const HashCoefficients& hashCoefficients() const {return mHashCoefficients;}
-    bool orderIsTotalDegreeRevLex() const {return mOrderIsTotalDegreeRevLex;}
-    Gradings& gradings() {return mGradings;} // todo: remove this overload
-    const Gradings& gradings() const {return mGradings;}
-    bool isLexBaseOrder() const {return mLexBaseOrder;}
-
-    static size_t gradingsIndex(
-      const VarIndex grading,
-      const VarIndex var,
-      const VarIndex varCount
-    ) {
-      MATHICGB_ASSERT(var < varCount);
-      return grading * static_cast<size_t>(varCount) + var;
-    }
-
-    size_t gradingsIndex(const VarIndex grading, const VarIndex var) const {
-      MATHICGB_ASSERT(grading < gradingCount());
-      MATHICGB_ASSERT(var < varCount());
-      const auto index = gradingsIndex(grading, var, varCount());
-      MATHICGB_ASSERT(index < gradings().size());
-      return index;
-    }
-
-    static size_t gradingsOppositeRowIndex(
-      const VarIndex grading,
-      const VarIndex gradingCount,
-      const VarIndex var,
-      const VarIndex varCount
-    ) {
-      MATHICGB_ASSERT(grading < gradingCount);
-      MATHICGB_ASSERT(var < varCount);
-      return gradingsIndex(gradingCount - 1 - grading, var, varCount);
-    }
-
-    size_t gradingsOppositeRowIndex(
-      const VarIndex grading,
-      const VarIndex var
-    ) const {
-      MATHICGB_ASSERT(grading < gradingCount());
-      MATHICGB_ASSERT(var < varCount());
-      const auto index =
-        gradingsOppositeRowIndex(grading, gradingCount(), var, varCount());
-      MATHICGB_ASSERT(index < gradings().size());
-      return index;
-    }
-
-  private:
-    HashCoefficients static makeHashCoefficients(const VarIndex varCount) {
-      std::srand(0); // To use the same hash coefficients every time.
-      HashCoefficients coeffs(varCount);
-      for (VarIndex var = 0; var < varCount; ++var)
-        coeffs[var] = static_cast<HashValue>(std::rand());
-      return coeffs;
-    }
-
-    const VarIndex mVarCount;
-    const VarIndex mGradingCount;
-    const VarIndex mOrderIndexBegin;
-    const VarIndex mOrderIndexEnd;
-    const VarIndex mEntryCount;
-    const VarIndex mComponentGradingIndex;
-
-    /// Take dot product of exponents with this vector to get hash value.
-    const HashCoefficients mHashCoefficients;
-
-    /// This is initialized before mGradings, so it has to be ordered
-    /// above mGradings. 
-    const bool mOrderIsTotalDegreeRevLex;
-
-    /// If true then lex is used to break ties. Otherwise, revlex is
-    /// used. This applies as well to degrees, which implies that
-    /// degrees have to be stored negated if doing revlex.
-    const bool mLexBaseOrder;
-    
-    /// Defines a matrix where each row is a grading. The degree of a
-    /// monomial with respect to grading g is the dot product of the
-    /// exponent vector of that monomial with row g of the matrix
-    /// (starting at g=0). The matrix is stored in row-major order. If
-    /// mOrderIsTotalDegreeRevLex is true then mGradings is empty but
-    /// implicitly it is a single grading consisting of all 1s and the
-    /// base order is revlex.
-    std::vector<Exponent> mGradings;    
-  };
-}
-
-template<class E, bool HC, bool SH, bool SO>
-class MonoMonoid : private MonoMonoidInternal::Base<E, HC, SH, SO> {
-private:
-  typedef MonoMonoidInternal::Base<E, HC, SH, SO> Base;
-
-public:
-  static_assert(std::numeric_limits<E>::is_signed, "");
-
-  // *** Types
-
-  // Integer index representing a variable. Indices start at 0 and go
-  // up to varCount() - 1 where varCount() is the number of variables.
-  typedef typename Base::VarIndex VarIndex;
-
-  /// The type of each exponent of a monomial.
-  typedef typename Base::Exponent Exponent;
-
-  /// Is true if the monomials come from a module.
-  using Base::HasComponent;
-
-  /// Is true if the hash value is stored rather than computed at each 
-  /// hash request. This imposes extra computation when updating a monomial,
-  /// but for most operations that overhead is much less than the time for
-  /// computing a hash value from scratch.
-  using Base::StoreHash;
-
-  /// Is true if data to compare monomials is stored rather than computed
-  /// at each comparison. As storeHash, there is overhead for this, but it
-  /// is not much for most operations.
-  using Base::StoreOrder;
-
-  /// Type used to indicate the component of a module monomial. For example,
-  /// the component of xe_3 is 3.
-  typedef typename Base::Component Component;
-
-  /// Type used to store hash values of monomials.
-  typedef typename Base::HashValue HashValue;
-
-  /// Iterator for the exponents in a monomial.
-  typedef typename Base::const_iterator const_iterator;
-
-  /// Represents a monomial and manages the memory underlying it. To
-  /// refer to a non-owned monomial or to refer to a Mono, use MonoRef
-  /// or ConstMonoRef. Do not use Mono& or Mono* if you do not have
-  /// to, since that implies a double indirection when accessing the
-  /// monomial.
-  class Mono;
-
-  /// A reference to a non-const monomial. Cannot be null, cannot be
-  /// reassigned to refer to a different monomial and does not connote
-  /// ownership - the same semantics as C++ references.
-  class MonoRef;
-
-  /// A reference to a monomial. As MonoRef, but you cannot change the
-  /// monomial through this reference. Prefer this class over the
-  /// other reference/pointer classes unless there is a reason not to.
-  class ConstMonoRef;
-
-  /// A pointer to a non-const monomial. Can be null and can be
-  /// reassigned to refer to a different monomial - the same semantics
-  /// as C++ pointers. Does not connote ownership.
-  class MonoPtr;
-
-  /// A pointer to a monomial. As MonoPtr, but you cannot change the
-  /// monomial through this pointer.
-  class ConstMonoPtr;
-
-  /// A pool of memory for monomials.
-  ///
-  /// @todo: This approach is a poor fit for variable-sized
-  /// monomials. So prefer other solutions where reasonable.
-  class MonoPool;
-
-  /// A vector of monomials. The interface is a subset of
-  /// std::vector. Monomials can be appended (push_back). Only the
-  /// last monomial can be mutated and monomials cannot be reordered
-  /// or removed. These restrictions should make it easier to support
-  /// variable-sized monomials in future. Change it if you need to
-  /// break these restrictions, but first try to find an alternative.
-  class MonoVector;
-
-  /// For indicating the result of comparing one monomial to another.
-  enum CompareResult {
-    LessThan = -1,
-    EqualTo = 0,
-    GreaterThan = 1
-  };
-
-  /// Used to describe a monomial order when constructing a monoid.
-  typedef typename Base::Order Order;
-
-  // *** Temporary compatibility code for migrating off PolyRing
-  friend class PolyRing;
-  friend class Poly;
-  static MonoRef toRef(Exponent* e) {return MonoRef(e);}
-  static ConstMonoRef toRef(const Exponent* e) {return ConstMonoRef(e);}
-  static Exponent* toOld(MonoRef e) {return rawPtr(e);}
-  static const Exponent* toOld(ConstMonoRef e) {return rawPtr(e);}
-
-
-  // *** Constructors and accessors
-
-  MonoMonoid(MonoMonoid&& monoid): Base(std::move(monoid)), mPool(*this) {
-    MATHICGB_ASSERT(debugAssertValid());
-  }
-
-  MonoMonoid(const MonoMonoid& monoid): Base(monoid), mPool(*this) {
-    MATHICGB_ASSERT(debugAssertValid());
-  }
-
-  MonoMonoid(const Order& order): Base(order), mPool(*this) {
-    MATHICGB_ASSERT(debugAssertValid());
-  }
-
-  /// Creates a compatible copy of monoid.
-  template<class E2, bool HC2, bool SH2, bool SO2>
-  static MonoMonoid create(const MonoMonoid<E2, HC2, SH2, SO2>& monoid) {
-    return MonoMonoid(monoid.makeOrder(false, false));
-  }
-
-  /// The second.first value of the return pair indicates whether it
-  /// is desired that i>j => e_i > e_j. the second.second value
-  /// indicates whether to do a Schreyer order. TODO: clearly this is
-  /// a mess that needs to be cleaned up. Step 1 is to move IO out of
-  /// MonoMonoid entirely.
-  static std::pair<MonoMonoid, std::pair<bool, bool>> readMonoid(std::istream& in);
-  void printMonoid
-    (const bool componentsAscendingDesired, std::ostream& out) const;
-
-  /// Returns an Order object that is equivalent to the order that
-  /// this monoid was constructed with. The settings not handled by
-  /// the monoid, and therefore not known by the monoid, are passed in
-  /// as parameters. The purpose of that is to make it clear that this
-  /// information must be supplied separately.
-  Order makeOrder(
-    const bool componentsAscendingDesired,
-    const bool schreyering
-  ) const {
-    std::vector<Exponent> orderGradings(gradings());
-    reverseGradings(varCount(), orderGradings);
-    if (!isLexBaseOrder())
-      negateGradings(orderGradings);
-    return Order(
-      varCount(),
-      std::move(orderGradings),
-      isLexBaseOrder() ? Order::LexBaseOrder : Order::RevLexBaseOrder,
-      Base::reverseComponentGradingIndex
-        (gradingCount(), componentGradingIndex()),
-      componentsAscendingDesired,
-      schreyering
-    );
-  }
-
-  bool operator==(const MonoMonoid& monoid) const {
-    return this == &monoid;
-  }
-
-  bool operator!=(const MonoMonoid& monoid) const {
-    return !(*this == monoid);
-  }
-
-  /// Returns true if higher component is considered greater when
-  /// comparing module monomials. Only relevant once actually
-  /// considering the component. This is only relevant for module
-  /// monomials.
-  bool componentsAscending() const {return isLexBaseOrder();}
-
-  /// Returns the number of variables. This is also the number of
-  /// exponents in the exponent vector of a monomial.
-  using Base::varCount;
-  //VarIndex varCount() const {return mVarCount;}
-
-
-  // *** Monomial accessors and queries
-
-  /// Returns iterator to the first exponent.
-  const_iterator begin(ConstMonoRef mono) const {
-    return ptr(mono, exponentsIndexBegin());
-  }
-
-  /// Returns iterator to one-past-the-end of the range of exponents.
-  const_iterator end(ConstMonoRef mono) const {
-    return ptr(mono, exponentsIndexEnd());
-  }
-
-  /// Returns the exponent of var in mono.
-  Exponent exponent(ConstMonoRef mono, const VarIndex var) const {
-    MATHICGB_ASSERT(var < varCount());
-    return access(mono, exponentsIndexBegin() + var);
-  } 
-
-  /// Returns the component of the monomial. Monomials not from a
-  /// module have component zero. In a module mono*e_i has component
-  /// i. @todo: Have different monoids for module monomials and
-  /// monomials and only offer this method for the module monomials.
-  Component component(ConstMonoRef mono) const {
-    MATHICGB_ASSERT(HasComponent);
-    return access(mono, componentIndex());
-  }
-
-  /// Returns a hash value for the monomial. These are not guaranteed
-  /// to be unique.
-  HashValue hash(ConstMonoRef mono) const {
-    MATHICGB_ASSERT(debugHashValid(mono));
-    if (StoreHash)
-      return static_cast<HashValue>(access(mono, hashIndex()));
-    else
-      return computeHash(mono);
-  }
-
-  /// Returns true if a and b are equal. Includes check for component.
-  bool equal(ConstMonoRef a, ConstMonoRef b) const {
-    for (auto i = entriesIndexBegin(); i != exponentsIndexEnd(); ++i)
-      if (access(a, i) != access(b, i))
-        return false;
-    return true;
-  }
-
-  template<class MonoidA>
-  bool equal(
-    const MonoidA& monoidA,
-    typename MonoidA::ConstMonoRef a,
-    ConstMonoRef b
-  ) const {
-    // todo: assert compatible
-    for (VarIndex var = 0; var < varCount(); ++var)
-      if (monoidA.exponent(a, var) != exponent(b, var))
-        return false;
-    return true;
-  }
-
-  /// As equal(), but optimized for the case where true is returned.
-  bool equalHintTrue(ConstMonoRef a, ConstMonoRef b) const {
-    // if a[i] != b[i] then a[i] ^ b[i] != 0, so the or of all xors is zero
-    // if and only if a equals b. This way we avoid having a branch to check
-    // equality for every iteration of the loop, which is a win in the case
-    // that none of the early-exit branches are taken - that is, when a equals
-    // b.
-    Exponent orOfXor = 0;
-    for (VarIndex i = lastExponentIndex(); i != beforeEntriesIndexBegin(); --i)
-      orOfXor |= access(a, i) ^ access(b, i);
-    MATHICGB_ASSERT((orOfXor == 0) == equal(a, b));
-    return orOfXor == 0;
-  }
-
-  bool isProductOf(
-    ConstMonoRef a,
-    ConstMonoRef b,
-    ConstMonoRef ab
-  ) const {
-    for (VarIndex i = entriesIndexBegin(); i != exponentsIndexEnd(); ++i)
-      if (access(ab, i) != access(a, i) + access(b, i))
-        return false;
-    return true;
-  }
-
-  bool isProductOfHintTrue(
-    ConstMonoRef a, 
-    ConstMonoRef b, 
-    ConstMonoRef ab
-  ) const {
-    // We compare more than one exponent at a time using 64 bit integers. This 
-    // might go one 32 bit value at the end too far, but since that space is
-    // either a degree or a hash value that is fine --- those values will also
-    // match if the monomials are equal. This does not work for negative
-    // exponents since the overflowing bit will go into the next word.
-    // It is OK that the degree field can be negative (a field we might go
-    // into without caring about it because it shares a 64 bit field with
-    // the last exponent), because it is at the end so the overflowing
-    // bit will not interfere. For this reason we need to have a degree
-    // or a hash value stored there - otherwise two equal monomials could
-    // have different things stored next to them which would confuse this code.
-    
-    // todo: ensure 8 byte alignment. Though there seem to be no ill effects
-    // for unaligned access. Performance seems to be no worse than for using
-    // 32 bit integers directly.
-
-    if (sizeof(Exponent) != 4 || (!StoreHash && !StoreOrder))
-      return isProductOf(a, b, ab);
-
-    uint64 orOfXor = 0;
-    for (VarIndex i = varCount() / 2; i != beforeEntriesIndexBegin(); --i) {
-      MATHICGB_ASSERT(access(a, i*2) >= 0);
-      MATHICGB_ASSERT(i == varCount() / 2 || access(a, i*2+1) >= 0);
-      
-      uint64 A, B, AB;
-      // We have to use std::memcpy here because just casting to a int64 breaks
-      // the strict aliasing rule which implies undefined behavior. Both MSVC and
-      // gcc don't actually call memcpy here. MSVC is a tiny bit slower for this
-      // code than for casting while GCC seems to be exactly the same speed.
-      std::memcpy(&A, ptr(a, i*2), 8);
-      std::memcpy(&B, ptr(b, i*2), 8);
-      std::memcpy(&AB, ptr(ab, i*2), 8);
-      orOfXor |= AB ^ (A + B);
-    }
-    MATHICGB_ASSERT((orOfXor == 0) == isProductOf(a, b, ab));
-    return orOfXor == 0; 
-  }
-
-  MATHICGB_INLINE bool isTwoProductsOfHintTrue(
-    ConstMonoRef a1,
-    ConstMonoRef a2,
-    ConstMonoRef b,
-    ConstMonoRef a1b,
-    ConstMonoRef a2b
-  ) const {
-    if (sizeof(Exponent) != 4 || (!StoreHash && !StoreOrder))
-      return (isProductOf(a1, b, a1b) && isProductOf(a2, b, a2b));
-
-    uint64 orOfXor = 0;
-    for (VarIndex i = varCount() / 2; i != beforeEntriesIndexBegin(); --i) {
-      uint64 A1, A2, B, A1B, A2B;
-      std::memcpy(&A1, ptr(a1, i*2), 8);
-      std::memcpy(&A2, ptr(a2, i*2), 8);
-      std::memcpy(&B, ptr(b, i*2), 8);
-      std::memcpy(&A1B, ptr(a1b, i*2), 8);
-      std::memcpy(&A2B, ptr(a2b, i*2), 8);
-      orOfXor |= (A1B ^ (A1 + B)) | (A2B ^ (A2 + B));
-    }
-    MATHICGB_ASSERT
-      ((orOfXor == 0) == (isProductOf(a1, b, a1b) && isProductOf(a2, b, a2b)));
-    return orOfXor == 0;
-  }
-
-  /// Returns the hash of the product of a and b.
-  HashValue hashOfProduct(ConstMonoRef a, ConstMonoRef b) const {
-    // See computeHash() for an explanation of all the casts.
-    const auto hashA = static_cast<HashValue>(hash(a));
-    const auto hashB = static_cast<HashValue>(hash(b));
-    return static_cast<HashValue>(static_cast<Exponent>(hashA + hashB));
-  }
-
-  /// Returns true if all the exponents of mono are zero. In other
-  /// words, returns true if mono is the identity for multiplication
-  /// of monomials.
-  bool isIdentity(ConstMonoRef mono) const {
-    return std::all_of(begin(mono), end(mono), [](Exponent e) {return e == 0;});
-  }
-
-  /// Returns true if a divides b. Equal monomials divide each other.
-  bool divides(ConstMonoRef div, ConstMonoRef into) const {
-    // todo: enable this when the code works with it
-    //if (HasComponent && component(div) != component(into))
-    //  return false;
-    for (auto i = exponentsIndexBegin(); i < exponentsIndexEnd(); ++i)
-      if (access(div, i) > access(into, i))
-        return false;
-    return true;
-  }
-
-  template<class MonoidA>
-  bool divides(
-    const MonoidA& monoidA,
-    typename MonoidA::ConstMonoRef a,
-    ConstMonoRef b
-  ) const {
-    // todo: fix other divisibility functions to work properly for component too.
-    MATHICGB_ASSERT(monoidA.varCount() == varCount());
-    MATHICGB_ASSERT(!MonoidA::HasComponent || HasComponent);
-    MATHICGB_ASSERT(monoidA.debugValid(a));
-    MATHICGB_ASSERT(debugValid(b));
-    // todo: enable this when the code works with it
-    //if (HasComponent && component(div) != component(into))
-    //  return false;
-    //if (
-    //  MonoidA::HasComponent &&
-    //  HasComponent &&
-    //  monoidA.component(a) != component(b)
-    //)
-    //  return false;
-    for (VarIndex var = 0; var < varCount(); ++var)
-      if (monoidA.exponent(a, var) > exponent(b, var))
-        return false;
-    return true;
-  }
-
-  /// Returns true if div divides lcm(a, b).
-  bool dividesLcm(ConstMonoRef div, ConstMonoRef a, ConstMonoRef b) const {
-    MATHICGB_ASSERT(debugLcmCheck(*this, a, *this, b));
-    MATHICGB_ASSERT(debugValid(div));
-
-    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i) {
-      const auto dive = access(div, i);
-      if (access(div, i) > access(a, i) && access(div, i) > access(b, i))
-        return false;
-    }
-    return true;
-  }
-
-  template<class MonoidDiv, class MonoidA>
-  bool dividesLcm(
-    const MonoidDiv& monoidDiv,
-    typename MonoidDiv::ConstMonoRef div,
-    const MonoidA& monoidA,
-    typename MonoidA::ConstMonoRef a,
-    ConstMonoRef b
-  ) const {
-    MATHICGB_ASSERT(monoidDiv.debugLcmCheck(monoidA, a, *this, b));
-    MATHICGB_ASSERT(monoidDiv.debugValid(div));
-
-    for (VarIndex var = 0; var < varCount(); ++var) {
-      const auto e = monoidDiv.exponent(div, var);
-      if (e > monoidA.exponent(a, var) && e > exponent(b, var))
-        return false;
-    }
-    return true;
-  }
-
-  /// Returns true if lcm(a,b) == lcmAB.
-  bool isLcm(ConstMonoRef a, ConstMonoRef b, ConstMonoRef lcmAB) const {
-    MATHICGB_ASSERT(debugLcmCheck(*this, a, *this, b));
-    MATHICGB_ASSERT(debugValid(lcmAB));
-
-    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i)
-      if (access(lcmAB, i) != std::max(access(a, i), access(b, i)))
-        return false;
-    return true;
-  }
-
-  template<class MonoidA, class MonoidB>
-  bool isLcm(
-    const MonoidA& monoidA,
-    typename MonoidA::ConstMonoRef a,
-    const MonoidB& monoidB,
-    typename MonoidB::ConstMonoRef b,
-    ConstMonoRef lcmAB
-  ) const {
-    MATHICGB_ASSERT(debugLcmCheck(monoidA, a, monoidB, b));
-    MATHICGB_ASSERT(debugValid(lcmAB));
-
-    if (HasComponent) {
-      if (MonoidA::HasComponent) {
-        if (monoidA.component(a) != component(lcmAB))
-          return false;
-      } else {
-        MATHICGB_ASSERT(MonoidB::HasComponent);
-        if (monoidB.component(b) != component(lcmAB))
-          return false;
-      }
-    }
-
-    for (VarIndex var = 0; var < varCount(); ++var) {
-      if (
-        ptr(lcmAB, exponentsIndexBegin())[var] !=
-        std::max(monoidA.exponent(a, var), monoidB.exponent(b, var))
-      )
-        return false;
-    }
-    return true;
-  }
-
-  CompareResult compare(ConstMonoRef a, ConstMonoRef b) const {
-    MATHICGB_ASSERT(debugOrderValid(a));
-    MATHICGB_ASSERT(debugOrderValid(b));
-
-    VarIndex index;
-    
-    if (StoreOrder)
-      index = orderIndexEnd();
-    else {
-      // Check the degrees seperately since they are not stored.
-      auto grading = gradingCount();
-      while (grading != 0) {
-        --grading;
-        const auto cmp = degree(a, grading) - degree(b, grading);
-        if (cmp < 0) return isLexBaseOrder() ? LessThan : GreaterThan;
-        if (cmp > 0) return isLexBaseOrder() ? GreaterThan : LessThan;
-      }
-      index = exponentsIndexEnd();
-    }
-
-    // If StoreOrder is true then this first checks the degrees.
-    // Then the exponents are checked.
-    // Finally, if HasComponent is true, the component is checked.
-    while (index != entriesIndexBegin()) {
-      --index;
-      const auto cmp = access(a, index) - access(b, index);
-      if (cmp < 0) return isLexBaseOrder() ? LessThan : GreaterThan;
-      if (cmp > 0) return isLexBaseOrder() ? GreaterThan : LessThan;
-    }
-    return EqualTo;
-  }
-
-  /// Compares a to b1*b2.
-  /// @todo: Test this method. Also, is this method actually useful, or could
-  /// it just as well be replaced by a multiplication and a comparison?
-  CompareResult compare(ConstMonoRef a, ConstMonoRef b1, ConstMonoRef b2) const {
-    MATHICGB_ASSERT(debugOrderValid(a));
-    MATHICGB_ASSERT(debugOrderValid(b1));
-    MATHICGB_ASSERT(debugOrderValid(b2));
-
-    VarIndex index;
-
-    if (StoreOrder)
-      index = orderIndexEnd();
-    else {
-      // Check the degrees seperately since they are not stored.
-      auto grading = gradingCount();
-      while (grading != 0) {
-        --grading;
-        const auto cmp =
-          degree(a, grading) - (degree(b1, grading) + degree(b2, grading));
-        if (cmp < 0) return isLexBaseOrder() ? LessThan : GreaterThan;
-        if (cmp > 0) return isLexBaseOrder() ? GreaterThan : LessThan;
-      }
-      index = exponentsIndexEnd();
-    }
-
-    // If StoreOrder is true then this first checks the degrees.
-    // Then the exponents are checked.
-    // Finally, if HasComponent is true, the component is checked.
-    while (index != entriesIndexBegin()) {
-      --index;
-      const auto cmp =
-        access(a, index) - (access(b1, index) + access(b2, index));
-      if (cmp < 0) return isLexBaseOrder() ? LessThan : GreaterThan;
-      if (cmp > 0) return isLexBaseOrder() ? GreaterThan : LessThan;
-    }
-    return EqualTo;
-  }
-
-  bool lessThan(ConstMonoRef a, ConstMonoRef b) const {
-    return compare(a, b) == LessThan;
-  }
-
-  /// Returns true if gcd(a, b) == 1.
-  bool relativelyPrime(ConstMonoRef a, ConstMonoRef b) const {
-    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i)
-      if (access(a, i) > 0 && access(b, i) > 0)
-        return false;
-    return true;
-  }
-
-  // If this method returns true for monomials a and b then it is
-  // guaranteed that multiplying a and b together will not overflow
-  // the integers in the representation.
-  bool hasAmpleCapacity(ConstMonoRef mono) const {
-    const auto halfMin = std::numeric_limits<Exponent>::min() / 2;
-    const auto halfMax = std::numeric_limits<Exponent>::max() / 2;
-    MATHICGB_ASSERT(halfMin <= 0);
-    const auto limit = std::min(-halfMin, halfMax);
-    const auto inRange = [&](Exponent value)
-      {return -limit <= value && value <= limit;};
-
-    for (VarIndex i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i)
-      if (!inRange(access(mono, i)))
-        return false;
-    for (VarIndex grading = 0; grading < gradingCount(); ++grading)
-      if (!inRange(degree(mono, grading)))
-        return false;
-    return true;
-  }
-
-  /// Returns the degree of mono using the most significant grading on
-  /// the monoid. This is the grading with index gradingCount() -
-  /// 1. This object must have at least one grading associated to it
-  /// before calling this method.
-  Exponent degree(ConstMonoRef mono) const {
-    MATHICGB_ASSERT(gradingCount() > 0);
-    return degree(mono, gradingCount() - 1);
-  }
-
-  /// Returns the degree of mono according to the grading with the
-  /// given index.
-  Exponent degree(ConstMonoRef mono, VarIndex grading) const {
-    MATHICGB_ASSERT(grading < gradingCount());
-    MATHICGB_ASSERT(debugOrderValid(mono));
-    if (StoreOrder)
-      return access(mono, orderIndexBegin() + grading);
-    else
-      return computeDegree(mono, grading);
-  }
-
-  /// Returns the number of gradings.
-  using Base::gradingCount;
-
-
-  // *** Monomial mutating computations
-
-  /// Copes the parameter from to the parameter to.
-  void copy(ConstMonoRef from, MonoRef to) const {
-    MATHICGB_ASSERT(debugValid(from));
-
-    std::copy_n(rawPtr(from), entryCount(), rawPtr(to));
-
-    MATHICGB_ASSERT(debugValid(to));
-  }
-
-  template<class MonoidFrom>
-  void copy(
-    const MonoidFrom& monoidFrom,
-    typename MonoidFrom::ConstMonoRef from,
-    MonoRef to
-  ) const {
-    // todo: extract this in checker method
-    MATHICGB_ASSERT(HasComponent == MonoidFrom::HasComponent);
-    MATHICGB_ASSERT(monoidFrom.debugValid(from));
-    MATHICGB_ASSERT(monoidFrom.varCount() == varCount());
-    MATHICGB_ASSERT
-      ((std::is_same<Exponent, typename MonoidFrom::Exponent>::value));
-
-    if (HasComponent)
-      access(to, componentIndex()) = monoidFrom.component(from);
-    const auto expsTo = ptr(to, exponentsIndexBegin());
-    for (VarIndex var = 0; var < varCount(); ++var)
-      expsTo[var] = monoidFrom.exponent(from, var);
-    if (StoreOrder) {
-      const auto degrees = ptr(to, orderIndexBegin());
-      for (VarIndex grading = 0; grading < gradingCount(); ++grading)
-        degrees[grading] = monoidFrom.degree(from, grading);
-    }
-    if (StoreHash)
-      access(to, hashIndex()) = monoidFrom.hash(from);
-
-    MATHICGB_ASSERT(debugValid(to));
-    // todo: check equal
-  }
-
-  /// Set the exponent of var to newExponent in mono.
-  void setExponent(
-    const VarIndex var,
-    const Exponent newExponent,
-    MonoRef mono
-  ) const {
-    MATHICGB_ASSERT(var < varCount());
-
-    auto& exponent = access(mono, exponentsIndexBegin() + var);
-    const auto oldExponent = exponent;
-    exponent = newExponent;
-
-    updateOrderData(var, oldExponent, newExponent, mono);
-    updateHashExponent(var, oldExponent, newExponent, mono);
-
-    MATHICGB_ASSERT(debugValid(mono));
-  }
-
-  /// Sets all the exponents of mono. exponents must point to an array
-  /// of size varCount().
-  void setExponents(const Exponent* exponents, MonoRef mono) const {
-    MATHICGB_ASSERT(exponents != 0);
-
-    if (HasComponent)
-      access(mono, componentIndex()) = 0;
-    std::copy_n(exponents, varCount(), ptr(mono, exponentsIndexBegin()));
-    setOrderData(mono);
-    setHash(mono);
-
-    MATHICGB_ASSERT(debugValid(mono));
-  }
-
-  /// Sets mono to 1, which is the identity for multiplication.
-  void setIdentity(MonoRef mono) const {
-    std::fill_n(rawPtr(mono), entryCount(), static_cast<Exponent>(0));
-
-    MATHICGB_ASSERT(debugValid(mono));
-    MATHICGB_ASSERT(isIdentity(mono));
-  }
-
-  /// Sets the component of mono to newComponent.
-  void setComponent(Component newComponent, MonoRef mono) const {
-    MATHICGB_ASSERT(HasComponent);
-
-    auto& component = access(mono, componentIndex());
-    const auto oldComponent = component;
-    component = newComponent;
-    updateHashComponent(oldComponent, newComponent, mono);
-    updateOrderComponent(newComponent, mono);
-
-    MATHICGB_ASSERT(debugValid(mono));
-  }
-
-  /// Sets prod to a*b.
-  void multiply(ConstMonoRef a, ConstMonoRef b, MonoRef prod) const {
-    MATHICGB_ASSERT(debugValid(a));
-    MATHICGB_ASSERT(debugValid(b));
-
-    for (auto i = lastEntryIndex(); i != beforeEntriesIndexBegin(); --i)
-      access(prod, i) = access(a, i) + access(b, i);
-
-    MATHICGB_ASSERT(debugValid(prod));
-  }
-
-  /// Sets prod to a*prod.
-  void multiplyInPlace(ConstMonoRef a, MonoRef prod) const {
-    MATHICGB_ASSERT(debugValid(a));
-    MATHICGB_ASSERT(debugValid(prod));
-
-    for (auto i = entriesIndexBegin(); i < entriesIndexEnd(); ++i)
-      access(prod, i) += access(a, i);
-
-    MATHICGB_ASSERT(debugValid(prod));      
-  }
-
-  /// Sets quo to num/by. by must divide num.
-  void divide(ConstMonoRef by, ConstMonoRef num, MonoRef quo) const {
-    MATHICGB_ASSERT(divides(by, num));
-    MATHICGB_ASSERT(debugValid(num));
-    MATHICGB_ASSERT(debugValid(by));
-
-    for (auto i = entriesIndexBegin(); i < entriesIndexEnd(); ++i)
-      access(quo, i) = access(num, i) - access(by, i);
-
-    MATHICGB_ASSERT(debugValid(quo));
-  }
-
-  /// Sets num to num/by. by must divide num.
-  void divideInPlace(ConstMonoRef by, MonoRef num) const {
-    MATHICGB_ASSERT(divides(by, num));
-    MATHICGB_ASSERT(debugValid(by));
-    MATHICGB_ASSERT(debugValid(num));
-
-    for (auto i = entriesIndexBegin(); i < entriesIndexEnd(); ++i)
-      access(num, i) -= access(by, i);
-
-    MATHICGB_ASSERT(debugValid(num));
-  }
-
-  /// Sets quo to num/by. If by does not divide num then quo will have
-  /// negative exponents.
-  void divideToNegative(ConstMonoRef by, ConstMonoRef num, MonoRef quo) const {
-    MATHICGB_ASSERT(debugValid(num));
-    MATHICGB_ASSERT(debugValid(by));
-    MATHICGB_ASSERT(
-      !HasComponent ||
-      component(by) == 0 ||
-      component(by) == component(num)
-    );
-
-    for (auto i = entriesIndexBegin(); i < entriesIndexEnd(); ++i)
-      access(quo, i) = access(num, i) - access(by, i);
-
-    MATHICGB_ASSERT(debugValid(quo));
-  }
-
-  /// Set out to (colonBy : colonNum) * mult.
-  /// @todo: test
-  void colonMultiply(
-    ConstMonoRef colonBy,
-    ConstMonoRef colonNum,
-    ConstMonoRef mult,
-    MonoRef out
-  ) const {
-    // todo: consider what happens with exponent overflow here
-    if (HasComponent) {
-      MATHICGB_ASSERT(component(colonBy) == component(colonNum));
-      access(out, componentIndex()) = component(mult);
-    }
-    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i) {
-      const auto colon = access(colonNum, i) - access(colonBy, i);
-      auto result = access(mult, i);
-      if (colon > 0)
-        result += colon;
-      access(out, i) = result;
-    }
-    setOrderData(out);
-    setHash(out);
-    MATHICGB_ASSERT(debugValid(out));
-  }
-
-  /// Returns the number of variables that divide mono.
-  /// @todo: test
-  VarIndex sizeOfSupport(ConstMonoRef mono) const {
-    VarIndex count = 0;
-    for (VarIndex var = 0; var < varCount(); ++var)
-      if (exponent(mono, var) != 0)
-        ++count;
-    return count;
-  }
-
-  /// Sets aColonB to a:b and bColonA to b:a.
-  void colons(
-    ConstMonoRef a,
-    ConstMonoRef b,
-    MonoRef aColonB,
-    MonoRef bColonA
-  ) const {
-    MATHICGB_ASSERT(debugValid(a));
-    MATHICGB_ASSERT(debugValid(b));
-
-    if (HasComponent) {
-      MATHICGB_ASSERT(component(a) == component(b));
-      access(aColonB, componentIndex()) = 0;
-      access(bColonA, componentIndex()) = 0;
-    }
-
-    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i) {
-      const auto ae = access(a, i);
-      const auto be = access(b, i);
-      const auto max = std::max(ae, be);
-      access(aColonB, i) = max - be;
-      access(bColonA, i) = max - ae;
-    }
-    setOrderData(aColonB);
-    setHash(aColonB);
-    setOrderData(bColonA);
-    setHash(bColonA);
-
-    MATHICGB_ASSERT(debugValid(aColonB));
-    MATHICGB_ASSERT(debugValid(bColonA));
-  }
-
-  /// Sets lcmAB to the lcm of a and b.
-  void lcm(ConstMonoRef a, ConstMonoRef b, MonoRef lcmAB) const {
-    if (HasComponent) {
-      MATHICGB_ASSERT(component(a) == component(b));
-      access(lcmAB, componentIndex()) = access(a, componentIndex());
-    }
-    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i)
-      access(lcmAB, i) = std::max(access(a, i), access(b, i));
-    setOrderData(lcmAB);
-    setHash(lcmAB);
-
-    MATHICGB_ASSERT(debugValid(lcmAB));
-    MATHICGB_ASSERT(isLcm(a, b, lcmAB));
-  }
-
-  template<class MonoidA, class MonoidB>
-  void lcm(
-    const MonoidA& monoidA,
-    typename MonoidA::ConstMonoRef a,
-    const MonoidB& monoidB,
-    typename MonoidB::ConstMonoRef b,
-    MonoRef lcmAB
-  ) const {
-    MATHICGB_ASSERT(debugLcmCheck(monoidA, a, monoidB, b));
-
-    if (HasComponent) {
-      access(lcmAB, componentIndex()) =
-        MonoidA::HasComponent ? monoidA.component(a) : monoidB.component(b);
-    }
-
-    for (VarIndex var = 0; var < varCount(); ++var) {
-      ptr(lcmAB, exponentsIndexBegin())[var] =
-        std::max(monoidA.exponent(a, var), monoidB.exponent(b, var));
-    }
-
-    setOrderData(lcmAB);
-    setHash(lcmAB);
-
-    MATHICGB_ASSERT(debugValid(lcmAB));
-    MATHICGB_ASSERT(isLcm(monoidA, a, monoidB, b, lcmAB));
-  }
-
-  Mono alloc() const {return mPool.alloc();}
-  void free(Mono&& mono) const {mPool.free(std::move(mono));}
-  void freeRaw(MonoRef mono) const {mPool.freeRaw(mono);}
-  bool fromPool(ConstMonoRef mono) const {mPool.fromPool(mono);}
-
-  /// Parses a monomial out of a string. Valid examples: 1 abc a2bc
-  /// aA. Variable names are case sensitive. Whitespace terminates the
-  /// parse as does any other character that is not a letter or a
-  /// digit.  The monomial must not include a coefficient, not even 1,
-  /// except for the special case of a 1 on its own. An input like 1a
-  /// will be parsed as two separate monomials. A suffix like <2> puts
-  /// the monomial in component 2, so a5<2> is a^5e_2. The default
-  /// component is 0.
-  void parseM2(std::istream& in, MonoRef mono) const;
-
-  // Inverse of parseM2().
-  void printM2(ConstMonoRef mono, std::ostream& out) const;
-
-  // As printM2, but returns a string.
-  std::string toString(ConstMonoRef mono) const {
-    std::ostringstream out;
-    printM2(mono, out);
-    return out.str();
-  }
-
-
-  // *** Classes for holding and referring to monomials
-
-  class ConstMonoPtr {
-  public:
-    ConstMonoPtr(): mMono(0) {}
-    ConstMonoPtr(const ConstMonoPtr& mono): mMono(rawPtr(mono)) {}
-
-    ConstMonoPtr operator=(const ConstMonoPtr& mono) {
-      mMono = mono.mMono;
-      return *this;
-    }
-
-    ConstMonoRef operator*() const {return *this;}
-
-    bool isNull() const {return mMono == 0;}
-    void toNull() {mMono = 0;}
-
-  private:
-    friend class MonoMonoid;
-
-    const Exponent* internalRawPtr() const {return mMono;}
-    ConstMonoPtr(const Exponent* mono): mMono(mono) {}
-
-    const Exponent* mMono;
-  };
-
-  class MonoPtr {
-  public:
-    MonoPtr(): mMono(0) {}
-    MonoPtr(const MonoPtr& mono): mMono(mono.mMono) {}
-
-    MonoPtr operator=(const MonoPtr& mono) {
-      mMono = mono.mMono;
-      return *this;
-    }
-
-    MonoRef operator*() const {return *this;}
-
-    bool isNull() const {return mMono == 0;}
-    void toNull() {mMono = 0;}
-
-    operator ConstMonoPtr() const {return ConstMonoPtr(mMono);}
-
-  private:
-    friend class MonoMonoid;
-    friend class PolyRing; // todo: remove
-    friend class Poly; // todo: remove
-
-    Exponent* internalRawPtr() const {return mMono;}
-    MonoPtr(Exponent* mono): mMono(mono) {}
-
-    Exponent* mMono;
-  };
-
-  class Mono : public NonCopyable<Mono> {
-  public:
-    Mono(): mMono(), mPool(0) {}
-
-    /// Passes ownership of the resources of mono to this object. Mono must
-    /// have been allocated from pool and it must have no other owner.
-    /// In particular, it must have been release()'ed from its original
-    /// owner.
-    Mono(MonoRef mono, MonoPool& pool):
-      mMono(mono.ptr()), mPool(&pool)
-    {
-      MATHICGB_ASSERT(pool.fromPool(mono));
-    }
-
-    Mono(Mono&& mono): mMono(mono.mMono), mPool(mono.mPool) {
-      mono.mMono.toNull();
-      mono.mPool = 0;
-    }
-
-    ~Mono() {toNull();}
-
-    void operator=(Mono&& mono) {
-      toNull();
-
-      mMono = mono.mMono;
-      mono.mMono.toNull();
-
-      mPool = mono.mPool;
-      mono.mPool = 0;
-    }
-
-    /// Sets this object to null but does NOT free the resources previously
-    /// held by this object. The returned MonoPtr points to the resources
-    /// that this object had prior to calling release(). If this object was
-    /// already null then the returned MonoPtr is also null.
-    MonoPtr release() {
-      const auto oldPtr = ptr();
-      mMono = 0;
-      mPool = 0;
-      return oldPtr;
-    }
-
-    bool isNull() const {return mMono.isNull();}
-    void toNull() {mPool->free(std::move(*this));}
-
-    MonoPtr ptr() const {return mMono;}
-
-    operator MonoRef() const {
-      MATHICGB_ASSERT(!isNull());
-      return *mMono;
-    }
-
-  private:
-    friend class MonoMonoid;
-
-    Exponent* internalRawPtr() const {return rawPtr(mMono);}
-
-    MonoPtr mMono;
-    MonoPool* mPool;
-  };
-
-  class MonoRef {
-  public:
-    MonoRef(const MonoRef& mono): mMono(mono.ptr()) {}
-
-    MonoPtr ptr() const {return mMono;}
-
-    operator ConstMonoRef() const {return *static_cast<ConstMonoPtr>(mMono);}
-
-  private:
-    void operator=(const MonoRef&); // not available
-    friend class MonoMonoid;
-
-    MonoRef(MonoPtr mono): mMono(mono) {}
-    Exponent* internalRawPtr() const {return rawPtr(mMono);}
-
-    const MonoPtr mMono;
-  };
-
-  class ConstMonoRef {
-  public:
-    ConstMonoRef(const ConstMonoRef& mono): mMono(mono.ptr()) {}
-    ConstMonoRef(const Mono& mono): mMono(mono.ptr()) {
-      MATHICGB_ASSERT(!mono.isNull());
-    }
-
-    ConstMonoPtr ptr() const {return mMono;}
-
-  private:
-    void operator=(const MonoRef&); // not available
-    friend class MonoMonoid;
-
-    ConstMonoRef(ConstMonoPtr mono): mMono(mono) {}
-    const Exponent* internalRawPtr() const {return rawPtr(mMono);}
-
-    const ConstMonoPtr mMono;
-  };
-
-
-  // *** Classes that provide memory resources for monomials
-
-  class MonoPool : public NonCopyable<MonoPool> {
-  public:
-    MonoPool(const MonoMonoid& monoid):
-      mMonoid(monoid),
-      mPool(sizeof(Exponent) * mMonoid.entryCount())
-    {}
-
-    MonoPool(MonoPool&& pool):
-      mMonoid(pool.mMonoid),
-      mPool(std::move(pool.mPool))
-    {}
-
-    Mono alloc() {
-      const auto ptr = static_cast<Exponent*>(mPool.alloc());
-      Mono mono(*MonoPtr(ptr), *this);
-      monoid().setIdentity(mono);
-      return mono;
-    }
-
-    void free(Mono&& mono) {
-      if (mono.isNull())
-        return;
-      freeRaw(mono);
-      mono.mMono = 0;
-      mono.mPool = 0;
-    }
-    void freeRaw(MonoRef mono) {mPool.free(rawPtr(mono));}
-
-    const MonoMonoid& monoid() const {return mMonoid;}
-
-    bool fromPool(ConstMonoRef mono) const {
-      return mPool.fromPool(rawPtr(mono));
-    }
-
-  private:
-    const MonoMonoid& mMonoid;
-    memt::BufferPool mPool;
-  };
-
-  class MonoVector {
-  private:
-    typedef std::vector<Exponent> RawVector;
-
-  public:
-    /// Class for iterating through the monomials in a MonoVector.
-    ///
-    /// There is no operator->() since MonoRef does not have any
-    /// relevant methods to call. Implement it if you need it.
-    ///
-    /// There are no postfix increment operator as prefix is
-    /// better. Add it if you y need it (you probably do not).
-    ///
-    /// We could make this a random access iterator, but that would
-    /// make it tricky to support variable-sized exponent vectors
-    /// (e.g. sparse) in future and so far we have not needed random
-    /// access.
-    class const_iterator {
-    public:
-      typedef std::forward_iterator_tag iterator_category;
-      typedef ConstMonoPtr value_type;
-    
-      const_iterator(): mIt(), mEntriesPerMono(0) {}
-      const_iterator(const const_iterator& it):
-        mIt(it.mIt), mEntriesPerMono(it.mEntriesPerMono) {}
-    
-      bool operator==(const const_iterator& it) const {return mIt == it.mIt;}
-      bool operator!=(const const_iterator& it) const {return mIt != it.mIt;}
-
-      ConstMonoRef operator*() {
-        MATHICGB_ASSERT(debugValid());
-        return *ConstMonoPtr(&*mIt);
-      }
-
-      const_iterator operator++() {
-        MATHICGB_ASSERT(debugValid());
-        mIt += mEntriesPerMono;
-        return *this;
-      }
-
-    private:
-      friend class MonoVector;
-      bool debugValid() {return mEntriesPerMono > 0;}
-
-      const_iterator(
-        typename RawVector::const_iterator it,
-        size_t entryCount
-      ): mIt(it), mEntriesPerMono(entryCount) {}
-      
-      typename RawVector::const_iterator mIt;
-      size_t mEntriesPerMono;		     
-    };
-
-    // ** Constructors and assignment
-    MonoVector(const MonoMonoid& monoid): mMonoid(monoid) {}
-    MonoVector(const MonoVector& v): mMonos(v.mMonos), mMonoid(v.monoid()) {}
-    MonoVector(MonoVector&& v):
-      mMonos(std::move(v.mMonos)), mMonoid(v.monoid()) {}
-
-    MonoVector& operator=(const MonoVector& v) {
-      MATHICGB_ASSERT(monoid() == v.monoid());
-      mMonos = v.mMonos;
-      return *this;
-    }
-
-    MonoVector& operator=(MonoVector&& v) {
-      MATHICGB_ASSERT(monoid() == v.monoid());
-      mMonos = std::move(v.mMonos);
-      return *this;      
-    }
-
-    // ** Iterators
-    const_iterator begin() const {
-      return const_iterator(mMonos.begin(), mMonoid.entryCount());
-    }
-
-    const_iterator end() const {
-      return const_iterator(mMonos.end(), mMonoid.entryCount());
-    }
-
-    const_iterator cbegin() const {return begin();}
-    const_iterator cend() const {return end();}
-
-    // ** Capacity
-    size_t size() const {return mMonos.size() / monoid().entryCount();}
-    bool empty() const {return mMonos.empty();}
-
-    // ** Element access
-    ConstMonoRef front() const {
-      MATHICGB_ASSERT(!empty());
-      return *begin();
-    }
-
-    MonoRef back() {
-      MATHICGB_ASSERT(!empty());
-      const auto offset = mMonos.size() - monoid().entryCount();
-      return *MonoPtr(mMonos.data() + offset);
-    }
-
-    ConstMonoRef back() const {
-      MATHICGB_ASSERT(!empty());
-      const auto offset = mMonos.size() - monoid().entryCount();
-      return *ConstMonoPtr(mMonos.data() + offset);
-    }
-
-    // ** Modifiers
-
-    void reserve(size_t count) {
-      mMonos.reserve(count * monoid().entryCount());
-    }
-
-    /// Appends the identity.
-    void push_back() {
-      const auto offset = mMonos.size();
-      mMonos.resize(offset + monoid().entryCount());
-      MATHICGB_ASSERT(monoid().isIdentity(back()));
-      MATHICGB_ASSERT(monoid().debugValid(back()));
-    }
-
-    void push_back(ConstMonoRef mono) {
-      MATHICGB_ASSERT(monoid().debugValid(mono));
-      const auto offset = mMonos.size();
-      mMonos.resize(offset + monoid().entryCount());
-      monoid().copy(mono, *MonoPtr(mMonos.data() + offset));
-      MATHICGB_ASSERT(monoid().debugValid(back()));
-    }
-
-    template<class Monoid>
-    void push_back(
-      const Monoid& monoidMono,
-      typename Monoid::ConstMonoRef mono
-    ) {
-      MATHICGB_ASSERT(monoidMono.debugValid(mono));
-      const auto offset = mMonos.size();
-      mMonos.resize(offset + monoid().entryCount());
-      monoid().copy(monoidMono, mono, *MonoPtr(mMonos.data() + offset));
-      MATHICGB_ASSERT(monoid().debugValid(back()));
-    }
-
-    void swap(MonoVector& v) {
-      MATHICGB_ASSERT(&monoid() == &v.monoid());
-      mMonos.swap(v.mMonos);
-    }
-
-    void clear() {mMonos.clear();}
-
-    // ** Relational operators
-    bool operator==(const MonoVector& v) const {
-      MATHICGB_ASSERT(monoid() == v.monoid());
-      return mMonos == v.mMonos;
-    }
-    bool operator!=(const MonoVector& v) const {return !(*this == v);}
-
-    // ** Other
-    size_t memoryBytesUsed() const {
-      return mMonos.capacity() * sizeof(mMonos[0]);
-    }
-
-    /// As parseM2 on monoid, but accepts a non-empty space-separated
-    /// list of monomials. The monomials are appended to the end of
-    /// the vector.
-    void parseM2(std::istream& in) {
-      while(true) {
-        push_back();
-        monoid().parseM2(in, back());
-        if (in.peek() != ' ')
-          break;
-        in.get();
-      }
-    }
-
-    /// The inverse of parseM2.
-    void printM2(std::ostream& out) const {
-      for (auto it = begin(); it != end(); ++it) {
-      if (it != begin())
-        out << ' ';
-       monoid().printM2(*it, out);
-      }
-      out << '\n';
-    }
-
-    const MonoMonoid& monoid() const {return mMonoid;}
-
-  private:
-    RawVector mMonos;
-    const MonoMonoid& mMonoid;
-  };
-
-
-private:
-  void operator=(MonoMonoid&); // not available
-
-  // Grants access to other template instantiations.
-  template<class E2, bool HC2, bool SH2, bool SO2>
-  friend class MonoMonoid;
-
-  // The main point here is to grant access to rawPtr().
-  friend class Mono;
-  friend class MonoRef;
-  friend class ConstMonoRef;
-  friend class MonoPtr;
-  friend class ConstMonoPtr;
-  friend class MonoVector;
-  friend class MonoPool;
-
-  typedef typename Base::Gradings Gradings;
-
-  bool debugAssertValid() const {
-#ifdef MATHICGB_DEBUG
-    // ** Order checks
-    MATHICGB_ASSERT(orderIndexBegin() == exponentsIndexEnd());
-    const auto storedDegrees = StoreOrder * gradingCount();
-    MATHICGB_ASSERT(orderIndexEnd() == orderIndexBegin() + storedDegrees);
-    MATHICGB_ASSERT(orderIndexEnd() <= entryCount());
-    if (orderIndexEnd() + StoreHash == 0) {
-      MATHICGB_ASSERT(entryCount() == 1);
-    } else {
-      MATHICGB_ASSERT(entryCount() == orderIndexEnd() + StoreHash);
-    }
-
-    MATHICGB_ASSERT(isLexBaseOrder() || varCount() == 0 || gradingCount() >= 1);
-
-    MATHICGB_ASSERT(gradings().size() == gradingCount() * varCount());
-    if (orderIsTotalDegreeRevLex()) {
-      MATHICGB_ASSERT(!isLexBaseOrder());
-      MATHICGB_ASSERT(gradingCount() == 1);
-    }
-
-    if (componentGradingIndex() != Order::ComponentAfterBaseOrder) {
-      MATHICGB_ASSERT(componentGradingIndex() < gradingCount());
-      for (VarIndex var = 0; var < varCount(); ++var) {
-        const auto index = gradingsIndex(componentGradingIndex(), var);
-        MATHICGB_ASSERT(gradings()[index] == 0);
-      }
-    }
-
-    // ** Hash checks
-    if (StoreHash) {
-      MATHICGB_ASSERT(hashIndex() < entryCount());
-      MATHICGB_ASSERT(hashIndex() == orderIndexEnd());
-    }
-    MATHICGB_ASSERT(hashCoefficients().size() == varCount());
-#endif
-    return true;
-  }
-
-  bool debugValid(ConstMonoRef mono) const {
-    MATHICGB_ASSERT(debugOrderValid(mono));
-    MATHICGB_ASSERT(debugHashValid(mono));
-    return true;
-  }
-
-  template<class MonoidA, class MonoidB>
-  bool debugLcmCheck(
-    const MonoidA& monoidA,
-    typename MonoidA::ConstMonoRef a,
-    const MonoidB& monoidB,
-    typename MonoidB::ConstMonoRef b
-  ) const {
-    MATHICGB_ASSERT(monoidA.varCount() == varCount());
-    MATHICGB_ASSERT(monoidB.varCount() == varCount());
-    MATHICGB_ASSERT
-      ((std::is_same<Exponent, typename MonoidA::Exponent>::value));
-    MATHICGB_ASSERT
-      ((std::is_same<Exponent, typename MonoidB::Exponent>::value));
-    MATHICGB_ASSERT
-      (HasComponent == (MonoidA::HasComponent || MonoidB::HasComponent));
-    MATHICGB_ASSERT(monoidA.debugValid(a));
-    MATHICGB_ASSERT(monoidB.debugValid(b));
-    MATHICGB_ASSERT(
-      !HasComponent ||
-      !MonoidA::HasComponent ||
-      !MonoidB::HasComponent ||
-      monoidA.component(a) == monoidB.component(b)
-  );
-
-    return true;
-  }
-
-  // *** Accessing fields of a monomial
-  template<class M>
-  static auto rawPtr(M&& m) -> decltype(m.internalRawPtr()) {
-    return m.internalRawPtr();
-  }
-
-  Exponent* ptr(MonoRef& m, const VarIndex index) const {
-    MATHICGB_ASSERT(index <= entryCount());
-    return rawPtr(m) + index;
-  }
-
-  const Exponent* ptr(ConstMonoRef& m, const VarIndex index) const {
-    MATHICGB_ASSERT(index <= entryCount());
-    return rawPtr(m) + index;
-  }
-
-  Exponent& access(MonoRef& m, const VarIndex index) const {
-    MATHICGB_ASSERT(index < entryCount());
-    return rawPtr(m)[index];
-  }
-
-  const Exponent& access(ConstMonoRef& m, const VarIndex index) const {
-    MATHICGB_ASSERT(index < entryCount());
-    return rawPtr(m)[index];
-  }
-
-  // *** Implementation of monomial ordering
-
-  using Base::gradingsOppositeRowIndex;
-  using Base::gradingsIndex;
-  using Base::reverseGradings;
-  using Base::negateGradings;
-
-  bool debugOrderValid(ConstMonoRef mono) const {
-#ifdef MATHICGB_DEBUG
-    if (!StoreOrder)
-      return true;
-    // Check the order data of mono
-    const auto degrees = ptr(mono, orderIndexBegin());
-    for (VarIndex grading = 0; grading < gradingCount(); ++grading) {
-      MATHICGB_ASSERT(degrees[grading] == computeDegree(mono, grading));
-    }
-#endif
-    return true;
-  }
-
-  void setOrderData(MonoRef mono) const {
-    if (!StoreOrder)
-      return;
-
-    const auto degrees = ptr(mono, orderIndexBegin());
-    for (VarIndex grading = 0; grading < gradingCount(); ++grading)
-      degrees[grading] = computeDegree(mono, grading);
-    MATHICGB_ASSERT(debugOrderValid(mono));
-  }
-
-  void updateOrderData(
-    const VarIndex var,
-    const Exponent oldExponent,
-    const Exponent newExponent,
-    MonoRef mono
-  ) const {
-    if (!StoreOrder)
-      return;
-
-    MATHICGB_ASSERT(var < varCount());
-    if (orderIsTotalDegreeRevLex())
-      rawPtr(mono)[orderIndexBegin()] -= newExponent - oldExponent;
-    else {
-      MATHICGB_ASSERT(gradings().size() == gradingCount() * varCount());
-      const auto degrees = ptr(mono, orderIndexBegin());
-      for (VarIndex grading = 0; grading < gradingCount(); ++grading) {
-        const auto index = gradingsIndex(grading, var);
-        degrees[grading] += gradings()[index] * ( newExponent - oldExponent);
-      }
-    }
-    MATHICGB_ASSERT(debugOrderValid(mono));
-  }
-
-  void updateOrderComponent(const VarIndex newComponent, MonoRef mono) const {
-    if (componentGradingIndex() != Order::ComponentAfterBaseOrder)
-      ptr(mono, orderIndexBegin())[componentGradingIndex()] = newComponent;
-  }
-
-  Exponent computeDegree(ConstMonoRef mono, VarIndex grading) const {
-    MATHICGB_ASSERT(grading < gradingCount());
-
-    Exponent degree = 0;
-    if (orderIsTotalDegreeRevLex()) {
-      MATHICGB_ASSERT(grading == 0);
-      for (auto var = 0; var < varCount(); ++var)
-        degree -= exponent(mono, var);
-    } else if (HasComponent && componentGradingIndex() == grading)
-      return component(mono);
-    else {
-      MATHICGB_ASSERT(gradings().size() == gradingCount() * varCount());
-      for (auto var = 0; var < varCount(); ++var) {
-        const auto index = gradingsIndex(grading, var);
-        degree += exponent(mono, var) * gradings()[index];
-      }
-    }
-    return degree;
-  }
-
-
-  // *** Implementation of hash value computation
-
-  bool debugHashValid(ConstMonoRef mono) const {
-    if (!StoreHash)
-      return true;
-
-    // We cannot call hash() here since it calls this method.
-    // todo: we cannot make this check right now because the legacy
-    // integration with PolyRing can create monomials with unset hash.
-    // MATHICGB_ASSERT(rawPtr(mono)[hashIndex()] == computeHash(mono));
-    return true;
-  }
-
-  HashValue computeHash(ConstMonoRef mono) const {
-    HashValue hash = HasComponent ? component(mono) : 0;
-    for (VarIndex var = 0; var < varCount(); ++var) {
-      hash +=
-        static_cast<HashValue>(exponent(mono, var)) * hashCoefficients()[var];
-    }
-
-    // Hash values are stored as exponents. If the cast to an exponent
-    // changes the value, then we need computeHashValue to match that
-    // change by casting to an exponent and back. Otherwise the computed
-    // hash value will not match a hash value that has been stored.
-    return static_cast<HashValue>(static_cast<Exponent>(hash));
-  }
-
-  void setHash(MonoRef mono) const {
-    if (!StoreHash)
-      return;
-    rawPtr(mono)[hashIndex()] = computeHash(mono);
-    MATHICGB_ASSERT(debugHashValid(mono));
-  }
-
-  void updateHashComponent(
-    const Exponent oldComponent,
-    const Exponent newComponent,
-    MonoRef mono
-  ) const {
-    if (!StoreHash)
-      return;
-    rawPtr(mono)[hashIndex()] += newComponent - oldComponent;
-    MATHICGB_ASSERT(debugHashValid(mono));
-  }
-
-  void updateHashExponent(
-    const VarIndex var,
-    const Exponent oldExponent,
-    const Exponent newExponent,
-    MonoRef mono
-  ) const {
-    if (!StoreHash)
-      return;
-    MATHICGB_ASSERT(var < varCount());
-    rawPtr(mono)[hashIndex()] +=
-      (newExponent - oldExponent) * hashCoefficients()[var];
-    MATHICGB_ASSERT(debugHashValid(mono));
-  }
-
-
-  // *** Code determining the layout of monomials in memory
-  // Layout in memory:
-  //   [component] [exponents...] [order data...] [hash]
-
-  /// Returns how many Exponents are necessary to store a
-  /// monomial. This can include other data than the exponents, so
-  /// this number can be larger than varCount().
-  using Base::entryCount;
-  //size_t entryCount() const {return mEntryCount;}
-
-  VarIndex componentIndex() const {
-    //static_assert(HasComponent, "");
-    return 0;
-  }
-
-  VarIndex exponentsIndexBegin() const {return HasComponent;}
-  VarIndex exponentsIndexEnd() const {return exponentsIndexBegin() + varCount();}
-  VarIndex lastExponentIndex() const {return exponentsIndexEnd() - 1;}
-
-  using Base::orderIndexBegin;
-  using Base::orderIndexEnd;
-  using Base::hashIndex;
-  using Base::orderIsTotalDegreeRevLex;
-  using Base::gradings;
-  using Base::isLexBaseOrder;
-  using Base::componentGradingIndex;
-
-  VarIndex entriesIndexBegin() const {return 0;}
-  VarIndex entriesIndexEnd() const {return entryCount();}
-  VarIndex beforeEntriesIndexBegin() const {return entriesIndexBegin() - 1;}
-  VarIndex lastEntryIndex() const {return entriesIndexEnd() - 1;}
-
-  using Base::hashCoefficients;
-
-  mutable MonoPool mPool;
-};
-
-namespace MonoMonoidHelper {
-  /// ostream and istream handle characters differently from other
-  /// integers. Use unchar to cast chars to a different type that get
-  /// handled as other integers do.
-  template<class T>
-  struct unchar {typedef int type;};
-
-  // Yes: char, signed char and unsigned char are 3 distinct types.
-  template<>
-  struct unchar<char> {typedef short type;};
-  template<>
-  struct unchar<signed char> {typedef short type;};
-  template<>
-  struct unchar<unsigned char> {typedef unsigned short type;};
-}
-
-template<class E, bool HC, bool SH, bool SO>
-auto MonoMonoid<E, HC, SH, SO>::readMonoid(std::istream& in) ->
-  std::pair<MonoMonoid, std::pair<bool, bool>>
-{
-  using MonoMonoidHelper::unchar;
-  VarIndex varCount;
-  in >> varCount;
-
-  bool doSchreyer = false;
-  bool lexBaseOrder = false;
-  std::string str;
-  char c;
-  in >> c;
-  in.unget();
-  if (!std::isdigit(c)) {
-    std::string str;
-    in >> str;
-    if (str == "schreyer") {
-      doSchreyer = true;
-      in >> str;
-    }
-
-    if (str == "revlex")
-      lexBaseOrder = false;
-    else if (str == "lex")
-      lexBaseOrder = true;
-    else
-      mathic::reportError("Expected lex or revlex but read \"" + str + "\".");
-  }
-
-  VarIndex gradingCount;
-  in >> gradingCount;
-
-  Gradings gradings(static_cast<size_t>(varCount) * gradingCount);
-  bool componentsAscendingDesired = true;
-  auto componentCompareIndex = Order::ComponentAfterBaseOrder;
-  size_t w = 0;
-  for (VarIndex grading = 0; grading <  gradingCount; ++grading) {
-    char c;
-    in >> c;
-    in.unget();
-    if (!std::isdigit(c)) {
-      std::string str;
-      in >> str;
-    
-      if (str == "component")
-        componentsAscendingDesired = true;
-      else if (str == "revcomponent")
-        componentsAscendingDesired = false;
-      else
-        mathic::reportError
-          ("Expected component or revcomponent but read \"" + str + "\".");
-      if (!HasComponent)
-        mathic::reportError
-          ("Cannot specify component comparison for non-modules.");
-      if (componentCompareIndex != Order::ComponentAfterBaseOrder)
-        mathic::reportError("Component must be considered at most once.");
-      componentCompareIndex = grading;
-      w += varCount;
-    } else {
-      for (VarIndex i = 0; i < varCount; ++i, ++w) {
-        typename unchar<Exponent>::type e;
-        in >> e;
-        gradings[w] = static_cast<Exponent>(e);
-      } 
-    }
-  }
-  MATHICGB_ASSERT(w == gradings.size());
-
-  in >> c;
-  in.unget();
-  if (c == '_') {
-    in >> str;
-
-    if (str == "_revlex")
-      lexBaseOrder = false;
-    else if (str == "_lex")
-      lexBaseOrder = true;
-    else
-      mathic::reportError("Expected _lex or _revlex but read \"" + str + "\".");
-
-    in >> c;
-    in.unget();
-    if (!std::isdigit(c)) {
-      in >> str;
-      if (str == "component")
-        componentsAscendingDesired = true;
-      else if (str == "revcomponent")
-        componentsAscendingDesired = false;
-      else
-        mathic::reportError
-          ("Expected component or revcomponent but read \"" + str + "\".");
-    }
-  }
-
-  Order order(
-    varCount,
-    std::move(gradings),
-    lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
-    componentCompareIndex
-  );
-  return std::make_pair(
-    MonoMonoid(order),
-    std::make_pair(componentsAscendingDesired, doSchreyer)
-  );
-}
-
-template<class E, bool HC, bool SH, bool SO>
-void MonoMonoid<E, HC, SH, SO>::printMonoid(
-  const bool componentsAscendingDesired,
-  std::ostream& out
-) const {
-  using MonoMonoidHelper::unchar;
-  typedef typename unchar<Exponent>::type UncharredExponent;
-
-  out << varCount() << '\n'
-      << (isLexBaseOrder() ? "lex" : "revlex")
-      << ' ' << gradingCount() << '\n';
-  MATHICGB_ASSERT(gradings().size() == gradingCount() * varCount());
-  for (VarIndex grading = 0; grading < gradingCount(); ++grading) {
-    if (
-      HasComponent &&
-      grading == gradingCount() - 1 - componentGradingIndex()
-    ) {
-      out << (componentsAscendingDesired ? " component\n" : " revcomponent\n");
-      continue;
-    }
-
-    for (VarIndex var = 0; var < varCount(); ++var) {
-      auto w = gradings()[gradingsOppositeRowIndex(grading, var)];
-      if (!isLexBaseOrder())
-        w = -w;
-      out << ' ' << static_cast<UncharredExponent>(w);
-    }
-    out << '\n';
-  }
-}
-
-template<class E, bool HC, bool SH, bool SO>
-void MonoMonoid<E, HC, SH, SO>::parseM2(std::istream& in, MonoRef mono) const {
-  using MonoMonoidHelper::unchar;
-  // todo: signal error on exponent overflow
-
-  setIdentity(mono);
-
-  bool sawSome = false;
-  while (true) {
-    const char next = in.peek();
-    if (!sawSome && next == '1') {
-      in.get();
-      break;
-    }
-
-    VarIndex var;
-    const auto letterCount = 'z' - 'a' + 1;
-    if ('a' <= next && next <= 'z')
-      var = next - 'a';
-    else if ('A' <= next && next <= 'Z')
-      var = (next - 'A') + letterCount;
-    else if (sawSome)
-      break;
-    else {
-      mathic::reportError("Could not parse monomial.");
-      return;
-    }
-    MATHICGB_ASSERT(var < 2 * letterCount);
-    if (var >= varCount()) {
-      mathic::reportError("Unknown variable.");
-      return;
-    }
-
-    in.get();
-    auto& exponent = access(mono, exponentsIndexBegin() + var);
-    if (isdigit(in.peek())) {
-      typename unchar<Exponent>::type e;
-      in >> e;
-      exponent = static_cast<Exponent>(e);
-    } else
-      exponent = 1;
-    sawSome = true;
-  }
-
-  if (in.peek() == '<') {
-    if (!HasComponent) {
-      mathic::reportError("Read unexpected < for start of module component\n");
-      return;
-    }
-
-    in.get();
-    if (!isdigit(in.peek())) {
-      mathic::reportError("Component was not integer.");
-      return;
-    }
-    typename unchar<Exponent>::type e;
-    in >> e;
-    access(mono, componentIndex()) = static_cast<Exponent>(e);
-    if (in.peek() != '>') {
-      mathic::reportError("Component < was not matched by >.");
-      return;
-    }
-    in.get();
-  }
-
-  setOrderData(mono);
-  setHash(mono);
-  MATHICGB_ASSERT(debugValid(mono));
-}
-
-template<class E, bool HC, bool SH, bool SO>
-void MonoMonoid<E, HC, SH, SO>::printM2(
-  ConstMonoRef mono,
-  std::ostream& out
-) const {
-  using MonoMonoidHelper::unchar;
-  const auto letterCount = 'z' - 'a' + 1;
-
-  bool printedSome = false;
-  for (VarIndex var = 0; var < varCount(); ++var) {
-    if (exponent(mono, var) == 0)
-      continue;
-    char letter;
-    if (var < letterCount)
-      letter = 'a' + static_cast<char>(var);
-    else if (var < 2 * letterCount)
-      letter = 'A' + (static_cast<char>(var) - letterCount);
-    else {
-      mathic::reportError("Too few letters in alphabet to print variable.");
-      return;
-    }
-    printedSome = true;
-    out << letter;
-    if (exponent(mono, var) != 1)
-      out << static_cast<typename unchar<Exponent>::type>(exponent(mono, var));
-  }
-  if (!printedSome)
-    out << '1';
-  if (HasComponent && component(mono) != 0) {
-    out << '<'
-        << static_cast<typename unchar<Exponent>::type>(component(mono))
-        << '>';
-  }
-}
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_MONO_MONOID_GUARD
+#define MATHICGB_MONO_MONOID_GUARD
+
+#include "MonoOrder.hpp"
+#include "NonCopyable.hpp"
+#include <vector>
+#include <algorithm>
+#include <memtailor.h>
+#include <type_traits>
+#include <istream>
+#include <utility>
+#include <ostream>
+#include <cstdlib>
+#include <cstring>
+#include <mathic.h>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// Implements the monoid of (monic) monomials with integer
+/// non-negative exponents. Exponent must be an unsigned integer type that is
+/// used to store each exponent of a monomial.
+template<
+  class Exponent,
+  bool HasComponent = true,
+  bool StoreHash = true,
+  bool StoreOrder = true
+>
+class MonoMonoid;
+
+namespace MonoMonoidInternal {
+  template<class E, bool HC, bool SH, bool SO>
+  class Base {
+  public:
+    static const bool HasComponent = HC;
+    static const bool StoreHash = SH;
+    static const bool StoreOrder = SO;
+
+    typedef size_t VarIndex;
+    typedef E Exponent;
+    typedef typename ::std::make_unsigned<E>::type Component;
+    typedef typename ::std::make_unsigned<E>::type HashValue;
+    typedef const Exponent* const_iterator;
+    typedef MonoOrder<Exponent> Order;
+
+    Base(const Order& order):
+      mVarCount(order.varCount()),
+      mGradingCount(order.gradingCount()),
+      mOrderIndexBegin(HasComponent + order.varCount()),
+      mOrderIndexEnd(mOrderIndexBegin + StoreOrder * order.gradingCount()),
+      mEntryCount(::std::max<VarIndex>(mOrderIndexEnd + StoreHash, 1)),
+      mHashCoefficients(makeHashCoefficients(order.varCount())),
+      mOrderIsTotalDegreeRevLex
+        (order.baseOrder() == Order::RevLexBaseOrder && order.isTotalDegree()),
+      mLexBaseOrder(order.baseOrder() == Order::LexBaseOrder),
+      mGradings(makeGradings(order)),
+      mComponentGradingIndex(
+        reverseComponentGradingIndex
+          (order.gradingCount(), order.componentGradingIndex())
+      )
+    {
+    }
+
+    VarIndex varCount() const {return mVarCount;}
+    VarIndex gradingCount() const {return mGradingCount;}
+
+    VarIndex entryCount() const {return mEntryCount;}
+    VarIndex orderIndexEnd() const {return mOrderIndexEnd;}
+    VarIndex orderIndexBegin() const {return mOrderIndexBegin;}
+    VarIndex hashIndex() const {return mOrderIndexEnd;}
+    VarIndex componentGradingIndex() const {return mComponentGradingIndex;}
+
+  protected:
+    typedef ::std::vector<Exponent> HashCoefficients;
+    typedef ::std::vector<Exponent> Gradings;
+
+    static Gradings makeGradings(const Order& order) {
+      auto gradings = order.gradings();
+      reverseGradings(order.varCount(), gradings);
+      if (order.baseOrder() == Order::RevLexBaseOrder)
+        negateGradings(gradings);
+      return gradings;
+    }
+
+    /// Reverse the relative order among the gradings - the first one
+    /// becomes the last one, the second first becomes the second last
+    /// and so on.
+    static void reverseGradings(const VarIndex varCount, Gradings& gradings) {
+      if (varCount == 0)
+        return;
+      MATHICGB_ASSERT(gradings.size() % varCount == 0);
+      const auto gradingCount = gradings.size() / varCount;
+
+      for (VarIndex grading = 0; grading < gradingCount / 2; ++grading) {
+        for (VarIndex var = 0; var < varCount; ++var) {
+          const auto index = gradingsIndex(grading, var, varCount);
+          const auto oppositeIndex = gradingsOppositeRowIndex
+            (grading, gradingCount, var, varCount);
+          ::std::swap(gradings[index], gradings[oppositeIndex]);
+        }
+      }
+    }
+
+    /// Replace each entry in the grading matrix with its negative.
+    static void negateGradings(Gradings& gradings) {
+      const auto size = gradings.size();
+      for (size_t i = 0; i < size; ++i)
+        gradings[i] = -gradings[i];
+    }
+
+    /// Since comparisons go opposite direction, we need to reverse
+    /// the component grading index, unless it's the special value
+    /// indicating that it goes last.
+    static VarIndex reverseComponentGradingIndex(
+      const VarIndex gradingCount,
+      const VarIndex componentGradingIndex
+    ) {
+      if (componentGradingIndex == Order::ComponentAfterBaseOrder)
+        return Order::ComponentAfterBaseOrder;
+      else
+        return gradingCount - 1 - componentGradingIndex;
+    }
+
+    const HashCoefficients& hashCoefficients() const {return mHashCoefficients;}
+    bool orderIsTotalDegreeRevLex() const {return mOrderIsTotalDegreeRevLex;}
+    Gradings& gradings() {return mGradings;} // todo: remove this overload
+    const Gradings& gradings() const {return mGradings;}
+    bool isLexBaseOrder() const {return mLexBaseOrder;}
+
+    static size_t gradingsIndex(
+      const VarIndex grading,
+      const VarIndex var,
+      const VarIndex varCount
+    ) {
+      MATHICGB_ASSERT(var < varCount);
+      return grading * static_cast<size_t>(varCount) + var;
+    }
+
+    size_t gradingsIndex(const VarIndex grading, const VarIndex var) const {
+      MATHICGB_ASSERT(grading < gradingCount());
+      MATHICGB_ASSERT(var < varCount());
+      const auto index = gradingsIndex(grading, var, varCount());
+      MATHICGB_ASSERT(index < gradings().size());
+      return index;
+    }
+
+    static size_t gradingsOppositeRowIndex(
+      const VarIndex grading,
+      const VarIndex gradingCount,
+      const VarIndex var,
+      const VarIndex varCount
+    ) {
+      MATHICGB_ASSERT(grading < gradingCount);
+      MATHICGB_ASSERT(var < varCount);
+      return gradingsIndex(gradingCount - 1 - grading, var, varCount);
+    }
+
+    size_t gradingsOppositeRowIndex(
+      const VarIndex grading,
+      const VarIndex var
+    ) const {
+      MATHICGB_ASSERT(grading < gradingCount());
+      MATHICGB_ASSERT(var < varCount());
+      const auto index =
+        gradingsOppositeRowIndex(grading, gradingCount(), var, varCount());
+      MATHICGB_ASSERT(index < gradings().size());
+      return index;
+    }
+
+  private:
+    HashCoefficients static makeHashCoefficients(const VarIndex varCount) {
+      ::std::srand(0); // To use the same hash coefficients every time.
+      HashCoefficients coeffs(varCount);
+      for (VarIndex var = 0; var < varCount; ++var)
+        coeffs[var] = static_cast<HashValue>(::std::rand());
+      return coeffs;
+    }
+
+    const VarIndex mVarCount;
+    const VarIndex mGradingCount;
+    const VarIndex mOrderIndexBegin;
+    const VarIndex mOrderIndexEnd;
+    const VarIndex mEntryCount;
+    const VarIndex mComponentGradingIndex;
+
+    /// Take dot product of exponents with this vector to get hash value.
+    const HashCoefficients mHashCoefficients;
+
+    /// This is initialized before mGradings, so it has to be ordered
+    /// above mGradings. 
+    const bool mOrderIsTotalDegreeRevLex;
+
+    /// If true then lex is used to break ties. Otherwise, revlex is
+    /// used. This applies as well to degrees, which implies that
+    /// degrees have to be stored negated if doing revlex.
+    const bool mLexBaseOrder;
+    
+    /// Defines a matrix where each row is a grading. The degree of a
+    /// monomial with respect to grading g is the dot product of the
+    /// exponent vector of that monomial with row g of the matrix
+    /// (starting at g=0). The matrix is stored in row-major order. If
+    /// mOrderIsTotalDegreeRevLex is true then mGradings is empty but
+    /// implicitly it is a single grading consisting of all 1s and the
+    /// base order is revlex.
+    ::std::vector<Exponent> mGradings;    
+  };
+}
+
+template<class E, bool HC, bool SH, bool SO>
+class MonoMonoid : private MonoMonoidInternal::Base<E, HC, SH, SO> {
+private:
+  typedef MonoMonoidInternal::Base<E, HC, SH, SO> Base;
+
+public:
+  static_assert(::std::numeric_limits<E>::is_signed, "");
+
+  // *** Types
+
+  // Integer index representing a variable. Indices start at 0 and go
+  // up to varCount() - 1 where varCount() is the number of variables.
+  typedef typename Base::VarIndex VarIndex;
+
+  /// The type of each exponent of a monomial.
+  typedef typename Base::Exponent Exponent;
+
+  /// Is true if the monomials come from a module.
+  using Base::HasComponent;
+
+  /// Is true if the hash value is stored rather than computed at each 
+  /// hash request. This imposes extra computation when updating a monomial,
+  /// but for most operations that overhead is much less than the time for
+  /// computing a hash value from scratch.
+  using Base::StoreHash;
+
+  /// Is true if data to compare monomials is stored rather than computed
+  /// at each comparison. As storeHash, there is overhead for this, but it
+  /// is not much for most operations.
+  using Base::StoreOrder;
+
+  /// Type used to indicate the component of a module monomial. For example,
+  /// the component of xe_3 is 3.
+  typedef typename Base::Component Component;
+
+  /// Type used to store hash values of monomials.
+  typedef typename Base::HashValue HashValue;
+
+  /// Iterator for the exponents in a monomial.
+  typedef typename Base::const_iterator const_iterator;
+
+  /// Represents a monomial and manages the memory underlying it. To
+  /// refer to a non-owned monomial or to refer to a Mono, use MonoRef
+  /// or ConstMonoRef. Do not use Mono& or Mono* if you do not have
+  /// to, since that implies a double indirection when accessing the
+  /// monomial.
+  class Mono;
+
+  /// A reference to a non-const monomial. Cannot be null, cannot be
+  /// reassigned to refer to a different monomial and does not connote
+  /// ownership - the same semantics as C++ references.
+  class MonoRef;
+
+  /// A reference to a monomial. As MonoRef, but you cannot change the
+  /// monomial through this reference. Prefer this class over the
+  /// other reference/pointer classes unless there is a reason not to.
+  class ConstMonoRef;
+
+  /// A pointer to a non-const monomial. Can be null and can be
+  /// reassigned to refer to a different monomial - the same semantics
+  /// as C++ pointers. Does not connote ownership.
+  class MonoPtr;
+
+  /// A pointer to a monomial. As MonoPtr, but you cannot change the
+  /// monomial through this pointer.
+  class ConstMonoPtr;
+
+  /// A pool of memory for monomials.
+  ///
+  /// @todo: This approach is a poor fit for variable-sized
+  /// monomials. So prefer other solutions where reasonable.
+  class MonoPool;
+
+  /// A vector of monomials. The interface is a subset of
+  /// ::std::vector. Monomials can be appended (push_back). Only the
+  /// last monomial can be mutated and monomials cannot be reordered
+  /// or removed. These restrictions should make it easier to support
+  /// variable-sized monomials in future. Change it if you need to
+  /// break these restrictions, but first try to find an alternative.
+  class MonoVector;
+
+  /// For indicating the result of comparing one monomial to another.
+  enum CompareResult {
+    LessThan = -1,
+    EqualTo = 0,
+    GreaterThan = 1
+  };
+
+  /// Used to describe a monomial order when constructing a monoid.
+  typedef typename Base::Order Order;
+
+  // *** Temporary compatibility code for migrating off PolyRing
+  friend class PolyRing;
+  friend class Poly;
+  static MonoRef toRef(Exponent* e) {return MonoRef(e);}
+  static ConstMonoRef toRef(const Exponent* e) {return ConstMonoRef(e);}
+  static Exponent* toOld(MonoRef e) {return rawPtr(e);}
+  static const Exponent* toOld(ConstMonoRef e) {return rawPtr(e);}
+
+
+  // *** Constructors and accessors
+
+  MonoMonoid(MonoMonoid&& monoid): Base(::std::move(monoid)), mPool(*this) {
+    MATHICGB_ASSERT(debugAssertValid());
+  }
+
+  MonoMonoid(const MonoMonoid& monoid): Base(monoid), mPool(*this) {
+    MATHICGB_ASSERT(debugAssertValid());
+  }
+
+  MonoMonoid(const Order& order): Base(order), mPool(*this) {
+    MATHICGB_ASSERT(debugAssertValid());
+  }
+
+  /// Creates a compatible copy of monoid.
+  template<class E2, bool HC2, bool SH2, bool SO2>
+  static MonoMonoid create(const MonoMonoid<E2, HC2, SH2, SO2>& monoid) {
+    return MonoMonoid(monoid.makeOrder(false, false));
+  }
+
+  /// The second.first value of the return pair indicates whether it
+  /// is desired that i>j => e_i > e_j. the second.second value
+  /// indicates whether to do a Schreyer order. TODO: clearly this is
+  /// a mess that needs to be cleaned up. Step 1 is to move IO out of
+  /// MonoMonoid entirely.
+  static ::std::pair<MonoMonoid, ::std::pair<bool, bool>> readMonoid(::std::istream& in);
+  void printMonoid
+    (const bool componentsAscendingDesired, ::std::ostream& out) const;
+
+  /// Returns an Order object that is equivalent to the order that
+  /// this monoid was constructed with. The settings not handled by
+  /// the monoid, and therefore not known by the monoid, are passed in
+  /// as parameters. The purpose of that is to make it clear that this
+  /// information must be supplied separately.
+  Order makeOrder(
+    const bool componentsAscendingDesired,
+    const bool schreyering
+  ) const {
+    ::std::vector<Exponent> orderGradings(gradings());
+    reverseGradings(varCount(), orderGradings);
+    if (!isLexBaseOrder())
+      negateGradings(orderGradings);
+    return Order(
+      varCount(),
+      ::std::move(orderGradings),
+      isLexBaseOrder() ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+      Base::reverseComponentGradingIndex
+        (gradingCount(), componentGradingIndex()),
+      componentsAscendingDesired,
+      schreyering
+    );
+  }
+
+  bool operator==(const MonoMonoid& monoid) const {
+    return this == &monoid;
+  }
+
+  bool operator!=(const MonoMonoid& monoid) const {
+    return !(*this == monoid);
+  }
+
+  /// Returns true if higher component is considered greater when
+  /// comparing module monomials. Only relevant once actually
+  /// considering the component. This is only relevant for module
+  /// monomials.
+  bool componentsAscending() const {return isLexBaseOrder();}
+
+  /// Returns the number of variables. This is also the number of
+  /// exponents in the exponent vector of a monomial.
+  using Base::varCount;
+  //VarIndex varCount() const {return mVarCount;}
+
+
+  // *** Monomial accessors and queries
+
+  /// Returns iterator to the first exponent.
+  const_iterator begin(ConstMonoRef mono) const {
+    return ptr(mono, exponentsIndexBegin());
+  }
+
+  /// Returns iterator to one-past-the-end of the range of exponents.
+  const_iterator end(ConstMonoRef mono) const {
+    return ptr(mono, exponentsIndexEnd());
+  }
+
+  /// Returns the exponent of var in mono.
+  Exponent exponent(ConstMonoRef mono, const VarIndex var) const {
+    MATHICGB_ASSERT(var < varCount());
+    return access(mono, exponentsIndexBegin() + var);
+  } 
+
+  /// Returns the component of the monomial. Monomials not from a
+  /// module have component zero. In a module mono*e_i has component
+  /// i. @todo: Have different monoids for module monomials and
+  /// monomials and only offer this method for the module monomials.
+  Component component(ConstMonoRef mono) const {
+    MATHICGB_ASSERT(HasComponent);
+    return access(mono, componentIndex());
+  }
+
+  /// Returns a hash value for the monomial. These are not guaranteed
+  /// to be unique.
+  HashValue hash(ConstMonoRef mono) const {
+    MATHICGB_ASSERT(debugHashValid(mono));
+    if (StoreHash)
+      return static_cast<HashValue>(access(mono, hashIndex()));
+    else
+      return computeHash(mono);
+  }
+
+  /// Returns true if a and b are equal. Includes check for component.
+  bool equal(ConstMonoRef a, ConstMonoRef b) const {
+    for (auto i = entriesIndexBegin(); i != exponentsIndexEnd(); ++i)
+      if (access(a, i) != access(b, i))
+        return false;
+    return true;
+  }
+
+  template<class MonoidA>
+  bool equal(
+    const MonoidA& monoidA,
+    typename MonoidA::ConstMonoRef a,
+    ConstMonoRef b
+  ) const {
+    // todo: assert compatible
+    for (VarIndex var = 0; var < varCount(); ++var)
+      if (monoidA.exponent(a, var) != exponent(b, var))
+        return false;
+    return true;
+  }
+
+  /// As equal(), but optimized for the case where true is returned.
+  bool equalHintTrue(ConstMonoRef a, ConstMonoRef b) const {
+    // if a[i] != b[i] then a[i] ^ b[i] != 0, so the or of all xors is zero
+    // if and only if a equals b. This way we avoid having a branch to check
+    // equality for every iteration of the loop, which is a win in the case
+    // that none of the early-exit branches are taken - that is, when a equals
+    // b.
+    Exponent orOfXor = 0;
+    for (VarIndex i = lastExponentIndex(); i != beforeEntriesIndexBegin(); --i)
+      orOfXor |= access(a, i) ^ access(b, i);
+    MATHICGB_ASSERT((orOfXor == 0) == equal(a, b));
+    return orOfXor == 0;
+  }
+
+  bool isProductOf(
+    ConstMonoRef a,
+    ConstMonoRef b,
+    ConstMonoRef ab
+  ) const {
+    for (VarIndex i = entriesIndexBegin(); i != exponentsIndexEnd(); ++i)
+      if (access(ab, i) != access(a, i) + access(b, i))
+        return false;
+    return true;
+  }
+
+  bool isProductOfHintTrue(
+    ConstMonoRef a, 
+    ConstMonoRef b, 
+    ConstMonoRef ab
+  ) const {
+    // We compare more than one exponent at a time using 64 bit integers. This 
+    // might go one 32 bit value at the end too far, but since that space is
+    // either a degree or a hash value that is fine --- those values will also
+    // match if the monomials are equal. This does not work for negative
+    // exponents since the overflowing bit will go into the next word.
+    // It is OK that the degree field can be negative (a field we might go
+    // into without caring about it because it shares a 64 bit field with
+    // the last exponent), because it is at the end so the overflowing
+    // bit will not interfere. For this reason we need to have a degree
+    // or a hash value stored there - otherwise two equal monomials could
+    // have different things stored next to them which would confuse this code.
+    
+    // todo: ensure 8 byte alignment. Though there seem to be no ill effects
+    // for unaligned access. Performance seems to be no worse than for using
+    // 32 bit integers directly.
+
+    if (sizeof(Exponent) != 4 || (!StoreHash && !StoreOrder))
+      return isProductOf(a, b, ab);
+
+    uint64 orOfXor = 0;
+    for (VarIndex i = varCount() / 2; i != beforeEntriesIndexBegin(); --i) {
+      MATHICGB_ASSERT(access(a, i*2) >= 0);
+      MATHICGB_ASSERT(i == varCount() / 2 || access(a, i*2+1) >= 0);
+      
+      uint64 A, B, AB;
+      // We have to use ::std::memcpy here because just casting to a int64 breaks
+      // the strict aliasing rule which implies undefined behavior. Both MSVC and
+      // gcc don't actually call memcpy here. MSVC is a tiny bit slower for this
+      // code than for casting while GCC seems to be exactly the same speed.
+      ::std::memcpy(&A, ptr(a, i*2), 8);
+      ::std::memcpy(&B, ptr(b, i*2), 8);
+      ::std::memcpy(&AB, ptr(ab, i*2), 8);
+      orOfXor |= AB ^ (A + B);
+    }
+    MATHICGB_ASSERT((orOfXor == 0) == isProductOf(a, b, ab));
+    return orOfXor == 0; 
+  }
+
+  MATHICGB_INLINE bool isTwoProductsOfHintTrue(
+    ConstMonoRef a1,
+    ConstMonoRef a2,
+    ConstMonoRef b,
+    ConstMonoRef a1b,
+    ConstMonoRef a2b
+  ) const {
+    if (sizeof(Exponent) != 4 || (!StoreHash && !StoreOrder))
+      return (isProductOf(a1, b, a1b) && isProductOf(a2, b, a2b));
+
+    uint64 orOfXor = 0;
+    for (VarIndex i = varCount() / 2; i != beforeEntriesIndexBegin(); --i) {
+      uint64 A1, A2, B, A1B, A2B;
+      ::std::memcpy(&A1, ptr(a1, i*2), 8);
+      ::std::memcpy(&A2, ptr(a2, i*2), 8);
+      ::std::memcpy(&B, ptr(b, i*2), 8);
+      ::std::memcpy(&A1B, ptr(a1b, i*2), 8);
+      ::std::memcpy(&A2B, ptr(a2b, i*2), 8);
+      orOfXor |= (A1B ^ (A1 + B)) | (A2B ^ (A2 + B));
+    }
+    MATHICGB_ASSERT
+      ((orOfXor == 0) == (isProductOf(a1, b, a1b) && isProductOf(a2, b, a2b)));
+    return orOfXor == 0;
+  }
+
+  /// Returns the hash of the product of a and b.
+  HashValue hashOfProduct(ConstMonoRef a, ConstMonoRef b) const {
+    // See computeHash() for an explanation of all the casts.
+    const auto hashA = static_cast<HashValue>(hash(a));
+    const auto hashB = static_cast<HashValue>(hash(b));
+    return static_cast<HashValue>(static_cast<Exponent>(hashA + hashB));
+  }
+
+  /// Returns true if all the exponents of mono are zero. In other
+  /// words, returns true if mono is the identity for multiplication
+  /// of monomials.
+  bool isIdentity(ConstMonoRef mono) const {
+    return ::std::all_of(begin(mono), end(mono), [](Exponent e) {return e == 0;});
+  }
+
+  /// Returns true if a divides b. Equal monomials divide each other.
+  bool divides(ConstMonoRef div, ConstMonoRef into) const {
+    // todo: enable this when the code works with it
+    //if (HasComponent && component(div) != component(into))
+    //  return false;
+    for (auto i = exponentsIndexBegin(); i < exponentsIndexEnd(); ++i)
+      if (access(div, i) > access(into, i))
+        return false;
+    return true;
+  }
+
+  template<class MonoidA>
+  bool divides(
+    const MonoidA& monoidA,
+    typename MonoidA::ConstMonoRef a,
+    ConstMonoRef b
+  ) const {
+    // todo: fix other divisibility functions to work properly for component too.
+    MATHICGB_ASSERT(monoidA.varCount() == varCount());
+    MATHICGB_ASSERT(!MonoidA::HasComponent || HasComponent);
+    MATHICGB_ASSERT(monoidA.debugValid(a));
+    MATHICGB_ASSERT(debugValid(b));
+    // todo: enable this when the code works with it
+    //if (HasComponent && component(div) != component(into))
+    //  return false;
+    //if (
+    //  MonoidA::HasComponent &&
+    //  HasComponent &&
+    //  monoidA.component(a) != component(b)
+    //)
+    //  return false;
+    for (VarIndex var = 0; var < varCount(); ++var)
+      if (monoidA.exponent(a, var) > exponent(b, var))
+        return false;
+    return true;
+  }
+
+  /// Returns true if div divides lcm(a, b).
+  bool dividesLcm(ConstMonoRef div, ConstMonoRef a, ConstMonoRef b) const {
+    MATHICGB_ASSERT(debugLcmCheck(*this, a, *this, b));
+    MATHICGB_ASSERT(debugValid(div));
+
+    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i) {
+      const auto dive = access(div, i);
+      if (access(div, i) > access(a, i) && access(div, i) > access(b, i))
+        return false;
+    }
+    return true;
+  }
+
+  template<class MonoidDiv, class MonoidA>
+  bool dividesLcm(
+    const MonoidDiv& monoidDiv,
+    typename MonoidDiv::ConstMonoRef div,
+    const MonoidA& monoidA,
+    typename MonoidA::ConstMonoRef a,
+    ConstMonoRef b
+  ) const {
+    MATHICGB_ASSERT(monoidDiv.debugLcmCheck(monoidA, a, *this, b));
+    MATHICGB_ASSERT(monoidDiv.debugValid(div));
+
+    for (VarIndex var = 0; var < varCount(); ++var) {
+      const auto e = monoidDiv.exponent(div, var);
+      if (e > monoidA.exponent(a, var) && e > exponent(b, var))
+        return false;
+    }
+    return true;
+  }
+
+  /// Returns true if lcm(a,b) == lcmAB.
+  bool isLcm(ConstMonoRef a, ConstMonoRef b, ConstMonoRef lcmAB) const {
+    MATHICGB_ASSERT(debugLcmCheck(*this, a, *this, b));
+    MATHICGB_ASSERT(debugValid(lcmAB));
+
+    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i)
+      if (access(lcmAB, i) != ::std::max(access(a, i), access(b, i)))
+        return false;
+    return true;
+  }
+
+  template<class MonoidA, class MonoidB>
+  bool isLcm(
+    const MonoidA& monoidA,
+    typename MonoidA::ConstMonoRef a,
+    const MonoidB& monoidB,
+    typename MonoidB::ConstMonoRef b,
+    ConstMonoRef lcmAB
+  ) const {
+    MATHICGB_ASSERT(debugLcmCheck(monoidA, a, monoidB, b));
+    MATHICGB_ASSERT(debugValid(lcmAB));
+
+    if (HasComponent) {
+      if (MonoidA::HasComponent) {
+        if (monoidA.component(a) != component(lcmAB))
+          return false;
+      } else {
+        MATHICGB_ASSERT(MonoidB::HasComponent);
+        if (monoidB.component(b) != component(lcmAB))
+          return false;
+      }
+    }
+
+    for (VarIndex var = 0; var < varCount(); ++var) {
+      if (
+        ptr(lcmAB, exponentsIndexBegin())[var] !=
+        ::std::max(monoidA.exponent(a, var), monoidB.exponent(b, var))
+      )
+        return false;
+    }
+    return true;
+  }
+
+  CompareResult compare(ConstMonoRef a, ConstMonoRef b) const {
+    MATHICGB_ASSERT(debugOrderValid(a));
+    MATHICGB_ASSERT(debugOrderValid(b));
+
+    VarIndex index;
+    
+    if (StoreOrder)
+      index = orderIndexEnd();
+    else {
+      // Check the degrees seperately since they are not stored.
+      auto grading = gradingCount();
+      while (grading != 0) {
+        --grading;
+        const auto cmp = degree(a, grading) - degree(b, grading);
+        if (cmp < 0) return isLexBaseOrder() ? LessThan : GreaterThan;
+        if (cmp > 0) return isLexBaseOrder() ? GreaterThan : LessThan;
+      }
+      index = exponentsIndexEnd();
+    }
+
+    // If StoreOrder is true then this first checks the degrees.
+    // Then the exponents are checked.
+    // Finally, if HasComponent is true, the component is checked.
+    while (index != entriesIndexBegin()) {
+      --index;
+      const auto cmp = access(a, index) - access(b, index);
+      if (cmp < 0) return isLexBaseOrder() ? LessThan : GreaterThan;
+      if (cmp > 0) return isLexBaseOrder() ? GreaterThan : LessThan;
+    }
+    return EqualTo;
+  }
+
+  /// Compares a to b1*b2.
+  /// @todo: Test this method. Also, is this method actually useful, or could
+  /// it just as well be replaced by a multiplication and a comparison?
+  CompareResult compare(ConstMonoRef a, ConstMonoRef b1, ConstMonoRef b2) const {
+    MATHICGB_ASSERT(debugOrderValid(a));
+    MATHICGB_ASSERT(debugOrderValid(b1));
+    MATHICGB_ASSERT(debugOrderValid(b2));
+
+    VarIndex index;
+
+    if (StoreOrder)
+      index = orderIndexEnd();
+    else {
+      // Check the degrees seperately since they are not stored.
+      auto grading = gradingCount();
+      while (grading != 0) {
+        --grading;
+        const auto cmp =
+          degree(a, grading) - (degree(b1, grading) + degree(b2, grading));
+        if (cmp < 0) return isLexBaseOrder() ? LessThan : GreaterThan;
+        if (cmp > 0) return isLexBaseOrder() ? GreaterThan : LessThan;
+      }
+      index = exponentsIndexEnd();
+    }
+
+    // If StoreOrder is true then this first checks the degrees.
+    // Then the exponents are checked.
+    // Finally, if HasComponent is true, the component is checked.
+    while (index != entriesIndexBegin()) {
+      --index;
+      const auto cmp =
+        access(a, index) - (access(b1, index) + access(b2, index));
+      if (cmp < 0) return isLexBaseOrder() ? LessThan : GreaterThan;
+      if (cmp > 0) return isLexBaseOrder() ? GreaterThan : LessThan;
+    }
+    return EqualTo;
+  }
+
+  bool lessThan(ConstMonoRef a, ConstMonoRef b) const {
+    return compare(a, b) == LessThan;
+  }
+
+  /// Returns true if gcd(a, b) == 1.
+  bool relativelyPrime(ConstMonoRef a, ConstMonoRef b) const {
+    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i)
+      if (access(a, i) > 0 && access(b, i) > 0)
+        return false;
+    return true;
+  }
+
+  // If this method returns true for monomials a and b then it is
+  // guaranteed that multiplying a and b together will not overflow
+  // the integers in the representation.
+  bool hasAmpleCapacity(ConstMonoRef mono) const {
+    const auto halfMin = ::std::numeric_limits<Exponent>::min() / 2;
+    const auto halfMax = ::std::numeric_limits<Exponent>::max() / 2;
+    MATHICGB_ASSERT(halfMin <= 0);
+    const auto limit = ::std::min(-halfMin, halfMax);
+    const auto inRange = [&](Exponent value)
+      {return -limit <= value && value <= limit;};
+
+    for (VarIndex i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i)
+      if (!inRange(access(mono, i)))
+        return false;
+    for (VarIndex grading = 0; grading < gradingCount(); ++grading)
+      if (!inRange(degree(mono, grading)))
+        return false;
+    return true;
+  }
+
+  /// Returns the degree of mono using the most significant grading on
+  /// the monoid. This is the grading with index gradingCount() -
+  /// 1. This object must have at least one grading associated to it
+  /// before calling this method.
+  Exponent degree(ConstMonoRef mono) const {
+    MATHICGB_ASSERT(gradingCount() > 0);
+    return degree(mono, gradingCount() - 1);
+  }
+
+  /// Returns the degree of mono according to the grading with the
+  /// given index.
+  Exponent degree(ConstMonoRef mono, VarIndex grading) const {
+    MATHICGB_ASSERT(grading < gradingCount());
+    MATHICGB_ASSERT(debugOrderValid(mono));
+    if (StoreOrder)
+      return access(mono, orderIndexBegin() + grading);
+    else
+      return computeDegree(mono, grading);
+  }
+
+  /// Returns the number of gradings.
+  using Base::gradingCount;
+
+
+  // *** Monomial mutating computations
+
+  /// Copes the parameter from to the parameter to.
+  void copy(ConstMonoRef from, MonoRef to) const {
+    MATHICGB_ASSERT(debugValid(from));
+
+    ::std::copy_n(rawPtr(from), entryCount(), rawPtr(to));
+
+    MATHICGB_ASSERT(debugValid(to));
+  }
+
+  template<class MonoidFrom>
+  void copy(
+    const MonoidFrom& monoidFrom,
+    typename MonoidFrom::ConstMonoRef from,
+    MonoRef to
+  ) const {
+    // todo: extract this in checker method
+    MATHICGB_ASSERT(HasComponent == MonoidFrom::HasComponent);
+    MATHICGB_ASSERT(monoidFrom.debugValid(from));
+    MATHICGB_ASSERT(monoidFrom.varCount() == varCount());
+    MATHICGB_ASSERT
+      ((::std::is_same<Exponent, typename MonoidFrom::Exponent>::value));
+
+    if (HasComponent)
+      access(to, componentIndex()) = monoidFrom.component(from);
+    const auto expsTo = ptr(to, exponentsIndexBegin());
+    for (VarIndex var = 0; var < varCount(); ++var)
+      expsTo[var] = monoidFrom.exponent(from, var);
+    if (StoreOrder) {
+      const auto degrees = ptr(to, orderIndexBegin());
+      for (VarIndex grading = 0; grading < gradingCount(); ++grading)
+        degrees[grading] = monoidFrom.degree(from, grading);
+    }
+    if (StoreHash)
+      access(to, hashIndex()) = monoidFrom.hash(from);
+
+    MATHICGB_ASSERT(debugValid(to));
+    // todo: check equal
+  }
+
+  /// Set the exponent of var to newExponent in mono.
+  void setExponent(
+    const VarIndex var,
+    const Exponent newExponent,
+    MonoRef mono
+  ) const {
+    MATHICGB_ASSERT(var < varCount());
+
+    auto& exponent = access(mono, exponentsIndexBegin() + var);
+    const auto oldExponent = exponent;
+    exponent = newExponent;
+
+    updateOrderData(var, oldExponent, newExponent, mono);
+    updateHashExponent(var, oldExponent, newExponent, mono);
+
+    MATHICGB_ASSERT(debugValid(mono));
+  }
+
+  /// Sets all the exponents of mono. exponents must point to an array
+  /// of size varCount().
+  void setExponents(const Exponent* exponents, MonoRef mono) const {
+    MATHICGB_ASSERT(exponents != 0);
+
+    if (HasComponent)
+      access(mono, componentIndex()) = 0;
+    ::std::copy_n(exponents, varCount(), ptr(mono, exponentsIndexBegin()));
+    setOrderData(mono);
+    setHash(mono);
+
+    MATHICGB_ASSERT(debugValid(mono));
+  }
+
+  /// Sets mono to 1, which is the identity for multiplication.
+  void setIdentity(MonoRef mono) const {
+    ::std::fill_n(rawPtr(mono), entryCount(), static_cast<Exponent>(0));
+
+    MATHICGB_ASSERT(debugValid(mono));
+    MATHICGB_ASSERT(isIdentity(mono));
+  }
+
+  /// Sets the component of mono to newComponent.
+  void setComponent(Component newComponent, MonoRef mono) const {
+    MATHICGB_ASSERT(HasComponent);
+
+    auto& component = access(mono, componentIndex());
+    const auto oldComponent = component;
+    component = newComponent;
+    updateHashComponent(oldComponent, newComponent, mono);
+    updateOrderComponent(newComponent, mono);
+
+    MATHICGB_ASSERT(debugValid(mono));
+  }
+
+  /// Sets prod to a*b.
+  void multiply(ConstMonoRef a, ConstMonoRef b, MonoRef prod) const {
+    MATHICGB_ASSERT(debugValid(a));
+    MATHICGB_ASSERT(debugValid(b));
+
+    for (auto i = lastEntryIndex(); i != beforeEntriesIndexBegin(); --i)
+      access(prod, i) = access(a, i) + access(b, i);
+
+    MATHICGB_ASSERT(debugValid(prod));
+  }
+
+  /// Sets prod to a*prod.
+  void multiplyInPlace(ConstMonoRef a, MonoRef prod) const {
+    MATHICGB_ASSERT(debugValid(a));
+    MATHICGB_ASSERT(debugValid(prod));
+
+    for (auto i = entriesIndexBegin(); i < entriesIndexEnd(); ++i)
+      access(prod, i) += access(a, i);
+
+    MATHICGB_ASSERT(debugValid(prod));      
+  }
+
+  /// Sets quo to num/by. by must divide num.
+  void divide(ConstMonoRef by, ConstMonoRef num, MonoRef quo) const {
+    MATHICGB_ASSERT(divides(by, num));
+    MATHICGB_ASSERT(debugValid(num));
+    MATHICGB_ASSERT(debugValid(by));
+
+    for (auto i = entriesIndexBegin(); i < entriesIndexEnd(); ++i)
+      access(quo, i) = access(num, i) - access(by, i);
+
+    MATHICGB_ASSERT(debugValid(quo));
+  }
+
+  /// Sets num to num/by. by must divide num.
+  void divideInPlace(ConstMonoRef by, MonoRef num) const {
+    MATHICGB_ASSERT(divides(by, num));
+    MATHICGB_ASSERT(debugValid(by));
+    MATHICGB_ASSERT(debugValid(num));
+
+    for (auto i = entriesIndexBegin(); i < entriesIndexEnd(); ++i)
+      access(num, i) -= access(by, i);
+
+    MATHICGB_ASSERT(debugValid(num));
+  }
+
+  /// Sets quo to num/by. If by does not divide num then quo will have
+  /// negative exponents.
+  void divideToNegative(ConstMonoRef by, ConstMonoRef num, MonoRef quo) const {
+    MATHICGB_ASSERT(debugValid(num));
+    MATHICGB_ASSERT(debugValid(by));
+    MATHICGB_ASSERT(
+      !HasComponent ||
+      component(by) == 0 ||
+      component(by) == component(num)
+    );
+
+    for (auto i = entriesIndexBegin(); i < entriesIndexEnd(); ++i)
+      access(quo, i) = access(num, i) - access(by, i);
+
+    MATHICGB_ASSERT(debugValid(quo));
+  }
+
+  /// Set out to (colonBy : colonNum) * mult.
+  /// @todo: test
+  void colonMultiply(
+    ConstMonoRef colonBy,
+    ConstMonoRef colonNum,
+    ConstMonoRef mult,
+    MonoRef out
+  ) const {
+    // todo: consider what happens with exponent overflow here
+    if (HasComponent) {
+      MATHICGB_ASSERT(component(colonBy) == component(colonNum));
+      access(out, componentIndex()) = component(mult);
+    }
+    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i) {
+      const auto colon = access(colonNum, i) - access(colonBy, i);
+      auto result = access(mult, i);
+      if (colon > 0)
+        result += colon;
+      access(out, i) = result;
+    }
+    setOrderData(out);
+    setHash(out);
+    MATHICGB_ASSERT(debugValid(out));
+  }
+
+  /// Returns the number of variables that divide mono.
+  /// @todo: test
+  VarIndex sizeOfSupport(ConstMonoRef mono) const {
+    VarIndex count = 0;
+    for (VarIndex var = 0; var < varCount(); ++var)
+      if (exponent(mono, var) != 0)
+        ++count;
+    return count;
+  }
+
+  /// Sets aColonB to a:b and bColonA to b:a.
+  void colons(
+    ConstMonoRef a,
+    ConstMonoRef b,
+    MonoRef aColonB,
+    MonoRef bColonA
+  ) const {
+    MATHICGB_ASSERT(debugValid(a));
+    MATHICGB_ASSERT(debugValid(b));
+
+    if (HasComponent) {
+      MATHICGB_ASSERT(component(a) == component(b));
+      access(aColonB, componentIndex()) = 0;
+      access(bColonA, componentIndex()) = 0;
+    }
+
+    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i) {
+      const auto ae = access(a, i);
+      const auto be = access(b, i);
+      const auto max = ::std::max(ae, be);
+      access(aColonB, i) = max - be;
+      access(bColonA, i) = max - ae;
+    }
+    setOrderData(aColonB);
+    setHash(aColonB);
+    setOrderData(bColonA);
+    setHash(bColonA);
+
+    MATHICGB_ASSERT(debugValid(aColonB));
+    MATHICGB_ASSERT(debugValid(bColonA));
+  }
+
+  /// Sets lcmAB to the lcm of a and b.
+  void lcm(ConstMonoRef a, ConstMonoRef b, MonoRef lcmAB) const {
+    if (HasComponent) {
+      MATHICGB_ASSERT(component(a) == component(b));
+      access(lcmAB, componentIndex()) = access(a, componentIndex());
+    }
+    for (auto i = exponentsIndexBegin(); i != exponentsIndexEnd(); ++i)
+      access(lcmAB, i) = ::std::max(access(a, i), access(b, i));
+    setOrderData(lcmAB);
+    setHash(lcmAB);
+
+    MATHICGB_ASSERT(debugValid(lcmAB));
+    MATHICGB_ASSERT(isLcm(a, b, lcmAB));
+  }
+
+  template<class MonoidA, class MonoidB>
+  void lcm(
+    const MonoidA& monoidA,
+    typename MonoidA::ConstMonoRef a,
+    const MonoidB& monoidB,
+    typename MonoidB::ConstMonoRef b,
+    MonoRef lcmAB
+  ) const {
+    MATHICGB_ASSERT(debugLcmCheck(monoidA, a, monoidB, b));
+
+    if (HasComponent) {
+      access(lcmAB, componentIndex()) =
+        MonoidA::HasComponent ? monoidA.component(a) : monoidB.component(b);
+    }
+
+    for (VarIndex var = 0; var < varCount(); ++var) {
+      ptr(lcmAB, exponentsIndexBegin())[var] =
+        ::std::max(monoidA.exponent(a, var), monoidB.exponent(b, var));
+    }
+
+    setOrderData(lcmAB);
+    setHash(lcmAB);
+
+    MATHICGB_ASSERT(debugValid(lcmAB));
+    MATHICGB_ASSERT(isLcm(monoidA, a, monoidB, b, lcmAB));
+  }
+
+  Mono alloc() const {return mPool.alloc();}
+  void free(Mono&& mono) const {mPool.free(::std::move(mono));}
+  void freeRaw(MonoRef mono) const {mPool.freeRaw(mono);}
+  bool fromPool(ConstMonoRef mono) const {mPool.fromPool(mono);}
+
+  /// Parses a monomial out of a string. Valid examples: 1 abc a2bc
+  /// aA. Variable names are case sensitive. Whitespace terminates the
+  /// parse as does any other character that is not a letter or a
+  /// digit.  The monomial must not include a coefficient, not even 1,
+  /// except for the special case of a 1 on its own. An input like 1a
+  /// will be parsed as two separate monomials. A suffix like <2> puts
+  /// the monomial in component 2, so a5<2> is a^5e_2. The default
+  /// component is 0.
+  void parseM2(::std::istream& in, MonoRef mono) const;
+
+  // Inverse of parseM2().
+  void printM2(ConstMonoRef mono, ::std::ostream& out) const;
+
+  // As printM2, but returns a string.
+  ::std::string toString(ConstMonoRef mono) const {
+    ::std::ostringstream out;
+    printM2(mono, out);
+    return out.str();
+  }
+
+
+  // *** Classes for holding and referring to monomials
+
+  class ConstMonoPtr {
+  public:
+    ConstMonoPtr(): mMono(0) {}
+    ConstMonoPtr(const ConstMonoPtr& mono): mMono(rawPtr(mono)) {}
+
+    ConstMonoPtr operator=(const ConstMonoPtr& mono) {
+      mMono = mono.mMono;
+      return *this;
+    }
+
+    ConstMonoRef operator*() const {return *this;}
+
+    bool isNull() const {return mMono == 0;}
+    void toNull() {mMono = 0;}
+
+  private:
+    friend class MonoMonoid;
+
+    const Exponent* internalRawPtr() const {return mMono;}
+    ConstMonoPtr(const Exponent* mono): mMono(mono) {}
+
+    const Exponent* mMono;
+  };
+
+  class MonoPtr {
+  public:
+    MonoPtr(): mMono(0) {}
+    MonoPtr(const MonoPtr& mono): mMono(mono.mMono) {}
+
+    MonoPtr operator=(const MonoPtr& mono) {
+      mMono = mono.mMono;
+      return *this;
+    }
+
+    MonoRef operator*() const {return *this;}
+
+    bool isNull() const {return mMono == 0;}
+    void toNull() {mMono = 0;}
+
+    operator ConstMonoPtr() const {return ConstMonoPtr(mMono);}
+
+  private:
+    friend class MonoMonoid;
+    friend class PolyRing; // todo: remove
+    friend class Poly; // todo: remove
+
+    Exponent* internalRawPtr() const {return mMono;}
+    MonoPtr(Exponent* mono): mMono(mono) {}
+
+    Exponent* mMono;
+  };
+
+  class Mono : public NonCopyable<Mono> {
+  public:
+    Mono(): mMono(), mPool(0) {}
+
+    /// Passes ownership of the resources of mono to this object. Mono must
+    /// have been allocated from pool and it must have no other owner.
+    /// In particular, it must have been release()'ed from its original
+    /// owner.
+    Mono(MonoRef mono, MonoPool& pool):
+      mMono(mono.ptr()), mPool(&pool)
+    {
+      MATHICGB_ASSERT(pool.fromPool(mono));
+    }
+
+    Mono(Mono&& mono): mMono(mono.mMono), mPool(mono.mPool) {
+      mono.mMono.toNull();
+      mono.mPool = 0;
+    }
+
+    ~Mono() {toNull();}
+
+    void operator=(Mono&& mono) {
+      toNull();
+
+      mMono = mono.mMono;
+      mono.mMono.toNull();
+
+      mPool = mono.mPool;
+      mono.mPool = 0;
+    }
+
+    /// Sets this object to null but does NOT free the resources previously
+    /// held by this object. The returned MonoPtr points to the resources
+    /// that this object had prior to calling release(). If this object was
+    /// already null then the returned MonoPtr is also null.
+    MonoPtr release() {
+      const auto oldPtr = ptr();
+      mMono = 0;
+      mPool = 0;
+      return oldPtr;
+    }
+
+    bool isNull() const {return mMono.isNull();}
+    void toNull() {mPool->free(::std::move(*this));}
+
+    MonoPtr ptr() const {return mMono;}
+
+    operator MonoRef() const {
+      MATHICGB_ASSERT(!isNull());
+      return *mMono;
+    }
+
+  private:
+    friend class MonoMonoid;
+
+    Exponent* internalRawPtr() const {return rawPtr(mMono);}
+
+    MonoPtr mMono;
+    MonoPool* mPool;
+  };
+
+  class MonoRef {
+  public:
+    MonoRef(const MonoRef& mono): mMono(mono.ptr()) {}
+
+    MonoPtr ptr() const {return mMono;}
+
+    operator ConstMonoRef() const {return *static_cast<ConstMonoPtr>(mMono);}
+
+  private:
+    void operator=(const MonoRef&); // not available
+    friend class MonoMonoid;
+
+    MonoRef(MonoPtr mono): mMono(mono) {}
+    Exponent* internalRawPtr() const {return rawPtr(mMono);}
+
+    const MonoPtr mMono;
+  };
+
+  class ConstMonoRef {
+  public:
+    ConstMonoRef(const ConstMonoRef& mono): mMono(mono.ptr()) {}
+    ConstMonoRef(const Mono& mono): mMono(mono.ptr()) {
+      MATHICGB_ASSERT(!mono.isNull());
+    }
+
+    ConstMonoPtr ptr() const {return mMono;}
+
+  private:
+    void operator=(const MonoRef&); // not available
+    friend class MonoMonoid;
+
+    ConstMonoRef(ConstMonoPtr mono): mMono(mono) {}
+    const Exponent* internalRawPtr() const {return rawPtr(mMono);}
+
+    const ConstMonoPtr mMono;
+  };
+
+
+  // *** Classes that provide memory resources for monomials
+
+  class MonoPool : public NonCopyable<MonoPool> {
+  public:
+    MonoPool(const MonoMonoid& monoid):
+      mMonoid(monoid),
+      mPool(sizeof(Exponent) * mMonoid.entryCount())
+    {}
+
+    MonoPool(MonoPool&& pool):
+      mMonoid(pool.mMonoid),
+      mPool(::std::move(pool.mPool))
+    {}
+
+    Mono alloc() {
+      const auto ptr = static_cast<Exponent*>(mPool.alloc());
+      Mono mono(*MonoPtr(ptr), *this);
+      monoid().setIdentity(mono);
+      return mono;
+    }
+
+    void free(Mono&& mono) {
+      if (mono.isNull())
+        return;
+      freeRaw(mono);
+      mono.mMono = 0;
+      mono.mPool = 0;
+    }
+    void freeRaw(MonoRef mono) {mPool.free(rawPtr(mono));}
+
+    const MonoMonoid& monoid() const {return mMonoid;}
+
+    bool fromPool(ConstMonoRef mono) const {
+      return mPool.fromPool(rawPtr(mono));
+    }
+
+  private:
+    const MonoMonoid& mMonoid;
+    memt::BufferPool mPool;
+  };
+
+  class MonoVector {
+  private:
+    typedef ::std::vector<Exponent> RawVector;
+
+  public:
+    /// Class for iterating through the monomials in a MonoVector.
+    ///
+    /// There is no operator->() since MonoRef does not have any
+    /// relevant methods to call. Implement it if you need it.
+    ///
+    /// There are no postfix increment operator as prefix is
+    /// better. Add it if you y need it (you probably do not).
+    ///
+    /// We could make this a random access iterator, but that would
+    /// make it tricky to support variable-sized exponent vectors
+    /// (e.g. sparse) in future and so far we have not needed random
+    /// access.
+    class const_iterator {
+    public:
+      typedef ::std::forward_iterator_tag iterator_category;
+      typedef ConstMonoPtr value_type;
+    
+      const_iterator(): mIt(), mEntriesPerMono(0) {}
+      const_iterator(const const_iterator& it):
+        mIt(it.mIt), mEntriesPerMono(it.mEntriesPerMono) {}
+    
+      bool operator==(const const_iterator& it) const {return mIt == it.mIt;}
+      bool operator!=(const const_iterator& it) const {return mIt != it.mIt;}
+
+      ConstMonoRef operator*() {
+        MATHICGB_ASSERT(debugValid());
+        return *ConstMonoPtr(&*mIt);
+      }
+
+      const_iterator operator++() {
+        MATHICGB_ASSERT(debugValid());
+        mIt += mEntriesPerMono;
+        return *this;
+      }
+
+    private:
+      friend class MonoVector;
+      bool debugValid() {return mEntriesPerMono > 0;}
+
+      const_iterator(
+        typename RawVector::const_iterator it,
+        size_t entryCount
+      ): mIt(it), mEntriesPerMono(entryCount) {}
+      
+      typename RawVector::const_iterator mIt;
+      size_t mEntriesPerMono;		     
+    };
+
+    // ** Constructors and assignment
+    MonoVector(const MonoMonoid& monoid): mMonoid(monoid) {}
+    MonoVector(const MonoVector& v): mMonos(v.mMonos), mMonoid(v.monoid()) {}
+    MonoVector(MonoVector&& v):
+      mMonos(::std::move(v.mMonos)), mMonoid(v.monoid()) {}
+
+    MonoVector& operator=(const MonoVector& v) {
+      MATHICGB_ASSERT(monoid() == v.monoid());
+      mMonos = v.mMonos;
+      return *this;
+    }
+
+    MonoVector& operator=(MonoVector&& v) {
+      MATHICGB_ASSERT(monoid() == v.monoid());
+      mMonos = ::std::move(v.mMonos);
+      return *this;      
+    }
+
+    // ** Iterators
+    const_iterator begin() const {
+      return const_iterator(mMonos.begin(), mMonoid.entryCount());
+    }
+
+    const_iterator end() const {
+      return const_iterator(mMonos.end(), mMonoid.entryCount());
+    }
+
+    const_iterator cbegin() const {return begin();}
+    const_iterator cend() const {return end();}
+
+    // ** Capacity
+    size_t size() const {return mMonos.size() / monoid().entryCount();}
+    bool empty() const {return mMonos.empty();}
+
+    // ** Element access
+    ConstMonoRef front() const {
+      MATHICGB_ASSERT(!empty());
+      return *begin();
+    }
+
+    MonoRef back() {
+      MATHICGB_ASSERT(!empty());
+      const auto offset = mMonos.size() - monoid().entryCount();
+      return *MonoPtr(mMonos.data() + offset);
+    }
+
+    ConstMonoRef back() const {
+      MATHICGB_ASSERT(!empty());
+      const auto offset = mMonos.size() - monoid().entryCount();
+      return *ConstMonoPtr(mMonos.data() + offset);
+    }
+
+    // ** Modifiers
+
+    void reserve(size_t count) {
+      mMonos.reserve(count * monoid().entryCount());
+    }
+
+    /// Appends the identity.
+    void push_back() {
+      const auto offset = mMonos.size();
+      mMonos.resize(offset + monoid().entryCount());
+      MATHICGB_ASSERT(monoid().isIdentity(back()));
+      MATHICGB_ASSERT(monoid().debugValid(back()));
+    }
+
+    void push_back(ConstMonoRef mono) {
+      MATHICGB_ASSERT(monoid().debugValid(mono));
+      const auto offset = mMonos.size();
+      mMonos.resize(offset + monoid().entryCount());
+      monoid().copy(mono, *MonoPtr(mMonos.data() + offset));
+      MATHICGB_ASSERT(monoid().debugValid(back()));
+    }
+
+    template<class Monoid>
+    void push_back(
+      const Monoid& monoidMono,
+      typename Monoid::ConstMonoRef mono
+    ) {
+      MATHICGB_ASSERT(monoidMono.debugValid(mono));
+      const auto offset = mMonos.size();
+      mMonos.resize(offset + monoid().entryCount());
+      monoid().copy(monoidMono, mono, *MonoPtr(mMonos.data() + offset));
+      MATHICGB_ASSERT(monoid().debugValid(back()));
+    }
+
+    void swap(MonoVector& v) {
+      MATHICGB_ASSERT(&monoid() == &v.monoid());
+      mMonos.swap(v.mMonos);
+    }
+
+    void clear() {mMonos.clear();}
+
+    // ** Relational operators
+    bool operator==(const MonoVector& v) const {
+      MATHICGB_ASSERT(monoid() == v.monoid());
+      return mMonos == v.mMonos;
+    }
+    bool operator!=(const MonoVector& v) const {return !(*this == v);}
+
+    // ** Other
+    size_t memoryBytesUsed() const {
+      return mMonos.capacity() * sizeof(mMonos[0]);
+    }
+
+    /// As parseM2 on monoid, but accepts a non-empty space-separated
+    /// list of monomials. The monomials are appended to the end of
+    /// the vector.
+    void parseM2(::std::istream& in) {
+      while(true) {
+        push_back();
+        monoid().parseM2(in, back());
+        if (in.peek() != ' ')
+          break;
+        in.get();
+      }
+    }
+
+    /// The inverse of parseM2.
+    void printM2(::std::ostream& out) const {
+      for (auto it = begin(); it != end(); ++it) {
+      if (it != begin())
+        out << ' ';
+       monoid().printM2(*it, out);
+      }
+      out << '\n';
+    }
+
+    const MonoMonoid& monoid() const {return mMonoid;}
+
+  private:
+    RawVector mMonos;
+    const MonoMonoid& mMonoid;
+  };
+
+
+private:
+  void operator=(MonoMonoid&); // not available
+
+  // Grants access to other template instantiations.
+  template<class E2, bool HC2, bool SH2, bool SO2>
+  friend class MonoMonoid;
+
+  // The main point here is to grant access to rawPtr().
+  friend class Mono;
+  friend class MonoRef;
+  friend class ConstMonoRef;
+  friend class MonoPtr;
+  friend class ConstMonoPtr;
+  friend class MonoVector;
+  friend class MonoPool;
+
+  typedef typename Base::Gradings Gradings;
+
+  bool debugAssertValid() const {
+#ifdef MATHICGB_DEBUG
+    // ** Order checks
+    MATHICGB_ASSERT(orderIndexBegin() == exponentsIndexEnd());
+    const auto storedDegrees = StoreOrder * gradingCount();
+    MATHICGB_ASSERT(orderIndexEnd() == orderIndexBegin() + storedDegrees);
+    MATHICGB_ASSERT(orderIndexEnd() <= entryCount());
+    if (orderIndexEnd() + StoreHash == 0) {
+      MATHICGB_ASSERT(entryCount() == 1);
+    } else {
+      MATHICGB_ASSERT(entryCount() == orderIndexEnd() + StoreHash);
+    }
+
+    MATHICGB_ASSERT(isLexBaseOrder() || varCount() == 0 || gradingCount() >= 1);
+
+    MATHICGB_ASSERT(gradings().size() == gradingCount() * varCount());
+    if (orderIsTotalDegreeRevLex()) {
+      MATHICGB_ASSERT(!isLexBaseOrder());
+      MATHICGB_ASSERT(gradingCount() == 1);
+    }
+
+    if (componentGradingIndex() != Order::ComponentAfterBaseOrder) {
+      MATHICGB_ASSERT(componentGradingIndex() < gradingCount());
+      for (VarIndex var = 0; var < varCount(); ++var) {
+        const auto index = gradingsIndex(componentGradingIndex(), var);
+        MATHICGB_ASSERT(gradings()[index] == 0);
+      }
+    }
+
+    // ** Hash checks
+    if (StoreHash) {
+      MATHICGB_ASSERT(hashIndex() < entryCount());
+      MATHICGB_ASSERT(hashIndex() == orderIndexEnd());
+    }
+    MATHICGB_ASSERT(hashCoefficients().size() == varCount());
+#endif
+    return true;
+  }
+
+  bool debugValid(ConstMonoRef mono) const {
+    MATHICGB_ASSERT(debugOrderValid(mono));
+    MATHICGB_ASSERT(debugHashValid(mono));
+    return true;
+  }
+
+  template<class MonoidA, class MonoidB>
+  bool debugLcmCheck(
+    const MonoidA& monoidA,
+    typename MonoidA::ConstMonoRef a,
+    const MonoidB& monoidB,
+    typename MonoidB::ConstMonoRef b
+  ) const {
+    MATHICGB_ASSERT(monoidA.varCount() == varCount());
+    MATHICGB_ASSERT(monoidB.varCount() == varCount());
+    MATHICGB_ASSERT
+      ((::std::is_same<Exponent, typename MonoidA::Exponent>::value));
+    MATHICGB_ASSERT
+      ((::std::is_same<Exponent, typename MonoidB::Exponent>::value));
+    MATHICGB_ASSERT
+      (HasComponent == (MonoidA::HasComponent || MonoidB::HasComponent));
+    MATHICGB_ASSERT(monoidA.debugValid(a));
+    MATHICGB_ASSERT(monoidB.debugValid(b));
+    MATHICGB_ASSERT(
+      !HasComponent ||
+      !MonoidA::HasComponent ||
+      !MonoidB::HasComponent ||
+      monoidA.component(a) == monoidB.component(b)
+  );
+
+    return true;
+  }
+
+  // *** Accessing fields of a monomial
+  template<class M>
+  static auto rawPtr(M&& m) -> decltype(m.internalRawPtr()) {
+    return m.internalRawPtr();
+  }
+
+  Exponent* ptr(MonoRef& m, const VarIndex index) const {
+    MATHICGB_ASSERT(index <= entryCount());
+    return rawPtr(m) + index;
+  }
+
+  const Exponent* ptr(ConstMonoRef& m, const VarIndex index) const {
+    MATHICGB_ASSERT(index <= entryCount());
+    return rawPtr(m) + index;
+  }
+
+  Exponent& access(MonoRef& m, const VarIndex index) const {
+    MATHICGB_ASSERT(index < entryCount());
+    return rawPtr(m)[index];
+  }
+
+  const Exponent& access(ConstMonoRef& m, const VarIndex index) const {
+    MATHICGB_ASSERT(index < entryCount());
+    return rawPtr(m)[index];
+  }
+
+  // *** Implementation of monomial ordering
+
+  using Base::gradingsOppositeRowIndex;
+  using Base::gradingsIndex;
+  using Base::reverseGradings;
+  using Base::negateGradings;
+
+  bool debugOrderValid(ConstMonoRef mono) const {
+#ifdef MATHICGB_DEBUG
+    if (!StoreOrder)
+      return true;
+    // Check the order data of mono
+    const auto degrees = ptr(mono, orderIndexBegin());
+    for (VarIndex grading = 0; grading < gradingCount(); ++grading) {
+      MATHICGB_ASSERT(degrees[grading] == computeDegree(mono, grading));
+    }
+#endif
+    return true;
+  }
+
+  void setOrderData(MonoRef mono) const {
+    if (!StoreOrder)
+      return;
+
+    const auto degrees = ptr(mono, orderIndexBegin());
+    for (VarIndex grading = 0; grading < gradingCount(); ++grading)
+      degrees[grading] = computeDegree(mono, grading);
+    MATHICGB_ASSERT(debugOrderValid(mono));
+  }
+
+  void updateOrderData(
+    const VarIndex var,
+    const Exponent oldExponent,
+    const Exponent newExponent,
+    MonoRef mono
+  ) const {
+    if (!StoreOrder)
+      return;
+
+    MATHICGB_ASSERT(var < varCount());
+    if (orderIsTotalDegreeRevLex())
+      rawPtr(mono)[orderIndexBegin()] -= newExponent - oldExponent;
+    else {
+      MATHICGB_ASSERT(gradings().size() == gradingCount() * varCount());
+      const auto degrees = ptr(mono, orderIndexBegin());
+      for (VarIndex grading = 0; grading < gradingCount(); ++grading) {
+        const auto index = gradingsIndex(grading, var);
+        degrees[grading] += gradings()[index] * ( newExponent - oldExponent);
+      }
+    }
+    MATHICGB_ASSERT(debugOrderValid(mono));
+  }
+
+  void updateOrderComponent(const VarIndex newComponent, MonoRef mono) const {
+    if (componentGradingIndex() != Order::ComponentAfterBaseOrder)
+      ptr(mono, orderIndexBegin())[componentGradingIndex()] = newComponent;
+  }
+
+  Exponent computeDegree(ConstMonoRef mono, VarIndex grading) const {
+    MATHICGB_ASSERT(grading < gradingCount());
+
+    Exponent degree = 0;
+    if (orderIsTotalDegreeRevLex()) {
+      MATHICGB_ASSERT(grading == 0);
+      for (auto var = 0; var < varCount(); ++var)
+        degree -= exponent(mono, var);
+    } else if (HasComponent && componentGradingIndex() == grading)
+      return component(mono);
+    else {
+      MATHICGB_ASSERT(gradings().size() == gradingCount() * varCount());
+      for (auto var = 0; var < varCount(); ++var) {
+        const auto index = gradingsIndex(grading, var);
+        degree += exponent(mono, var) * gradings()[index];
+      }
+    }
+    return degree;
+  }
+
+
+  // *** Implementation of hash value computation
+
+  bool debugHashValid(ConstMonoRef mono) const {
+    if (!StoreHash)
+      return true;
+
+    // We cannot call hash() here since it calls this method.
+    // todo: we cannot make this check right now because the legacy
+    // integration with PolyRing can create monomials with unset hash.
+    // MATHICGB_ASSERT(rawPtr(mono)[hashIndex()] == computeHash(mono));
+    return true;
+  }
+
+  HashValue computeHash(ConstMonoRef mono) const {
+    HashValue hash = HasComponent ? component(mono) : 0;
+    for (VarIndex var = 0; var < varCount(); ++var) {
+      hash +=
+        static_cast<HashValue>(exponent(mono, var)) * hashCoefficients()[var];
+    }
+
+    // Hash values are stored as exponents. If the cast to an exponent
+    // changes the value, then we need computeHashValue to match that
+    // change by casting to an exponent and back. Otherwise the computed
+    // hash value will not match a hash value that has been stored.
+    return static_cast<HashValue>(static_cast<Exponent>(hash));
+  }
+
+  void setHash(MonoRef mono) const {
+    if (!StoreHash)
+      return;
+    rawPtr(mono)[hashIndex()] = computeHash(mono);
+    MATHICGB_ASSERT(debugHashValid(mono));
+  }
+
+  void updateHashComponent(
+    const Exponent oldComponent,
+    const Exponent newComponent,
+    MonoRef mono
+  ) const {
+    if (!StoreHash)
+      return;
+    rawPtr(mono)[hashIndex()] += newComponent - oldComponent;
+    MATHICGB_ASSERT(debugHashValid(mono));
+  }
+
+  void updateHashExponent(
+    const VarIndex var,
+    const Exponent oldExponent,
+    const Exponent newExponent,
+    MonoRef mono
+  ) const {
+    if (!StoreHash)
+      return;
+    MATHICGB_ASSERT(var < varCount());
+    rawPtr(mono)[hashIndex()] +=
+      (newExponent - oldExponent) * hashCoefficients()[var];
+    MATHICGB_ASSERT(debugHashValid(mono));
+  }
+
+
+  // *** Code determining the layout of monomials in memory
+  // Layout in memory:
+  //   [component] [exponents...] [order data...] [hash]
+
+  /// Returns how many Exponents are necessary to store a
+  /// monomial. This can include other data than the exponents, so
+  /// this number can be larger than varCount().
+  using Base::entryCount;
+  //size_t entryCount() const {return mEntryCount;}
+
+  VarIndex componentIndex() const {
+    //static_assert(HasComponent, "");
+    return 0;
+  }
+
+  VarIndex exponentsIndexBegin() const {return HasComponent;}
+  VarIndex exponentsIndexEnd() const {return exponentsIndexBegin() + varCount();}
+  VarIndex lastExponentIndex() const {return exponentsIndexEnd() - 1;}
+
+  using Base::orderIndexBegin;
+  using Base::orderIndexEnd;
+  using Base::hashIndex;
+  using Base::orderIsTotalDegreeRevLex;
+  using Base::gradings;
+  using Base::isLexBaseOrder;
+  using Base::componentGradingIndex;
+
+  VarIndex entriesIndexBegin() const {return 0;}
+  VarIndex entriesIndexEnd() const {return entryCount();}
+  VarIndex beforeEntriesIndexBegin() const {return entriesIndexBegin() - 1;}
+  VarIndex lastEntryIndex() const {return entriesIndexEnd() - 1;}
+
+  using Base::hashCoefficients;
+
+  mutable MonoPool mPool;
+};
+
+namespace MonoMonoidHelper {
+  /// ostream and istream handle characters differently from other
+  /// integers. Use unchar to cast chars to a different type that get
+  /// handled as other integers do.
+  template<class T>
+  struct unchar {typedef int type;};
+
+  // Yes: char, signed char and unsigned char are 3 distinct types.
+  template<>
+  struct unchar<char> {typedef short type;};
+  template<>
+  struct unchar<signed char> {typedef short type;};
+  template<>
+  struct unchar<unsigned char> {typedef unsigned short type;};
+}
+
+template<class E, bool HC, bool SH, bool SO>
+auto MonoMonoid<E, HC, SH, SO>::readMonoid(::std::istream& in) ->
+  ::std::pair<MonoMonoid, ::std::pair<bool, bool>>
+{
+  using MonoMonoidHelper::unchar;
+  VarIndex varCount;
+  in >> varCount;
+
+  bool doSchreyer = false;
+  bool lexBaseOrder = false;
+  ::std::string str;
+  char c;
+  in >> c;
+  in.unget();
+  if (!::std::isdigit(c)) {
+    ::std::string str;
+    in >> str;
+    if (str == "schreyer") {
+      doSchreyer = true;
+      in >> str;
+    }
+
+    if (str == "revlex")
+      lexBaseOrder = false;
+    else if (str == "lex")
+      lexBaseOrder = true;
+    else
+      mathic::reportError("Expected lex or revlex but read \"" + str + "\".");
+  }
+
+  VarIndex gradingCount;
+  in >> gradingCount;
+
+  Gradings gradings(static_cast<size_t>(varCount) * gradingCount);
+  bool componentsAscendingDesired = true;
+  auto componentCompareIndex = Order::ComponentAfterBaseOrder;
+  size_t w = 0;
+  for (VarIndex grading = 0; grading <  gradingCount; ++grading) {
+    char c;
+    in >> c;
+    in.unget();
+    if (!::std::isdigit(c)) {
+      ::std::string str;
+      in >> str;
+    
+      if (str == "component")
+        componentsAscendingDesired = true;
+      else if (str == "revcomponent")
+        componentsAscendingDesired = false;
+      else
+        mathic::reportError
+          ("Expected component or revcomponent but read \"" + str + "\".");
+      if (!HasComponent)
+        mathic::reportError
+          ("Cannot specify component comparison for non-modules.");
+      if (componentCompareIndex != Order::ComponentAfterBaseOrder)
+        mathic::reportError("Component must be considered at most once.");
+      componentCompareIndex = grading;
+      w += varCount;
+    } else {
+      for (VarIndex i = 0; i < varCount; ++i, ++w) {
+        typename unchar<Exponent>::type e;
+        in >> e;
+        gradings[w] = static_cast<Exponent>(e);
+      } 
+    }
+  }
+  MATHICGB_ASSERT(w == gradings.size());
+
+  in >> c;
+  in.unget();
+  if (c == '_') {
+    in >> str;
+
+    if (str == "_revlex")
+      lexBaseOrder = false;
+    else if (str == "_lex")
+      lexBaseOrder = true;
+    else
+      mathic::reportError("Expected _lex or _revlex but read \"" + str + "\".");
+
+    in >> c;
+    in.unget();
+    if (!::std::isdigit(c)) {
+      in >> str;
+      if (str == "component")
+        componentsAscendingDesired = true;
+      else if (str == "revcomponent")
+        componentsAscendingDesired = false;
+      else
+        mathic::reportError
+          ("Expected component or revcomponent but read \"" + str + "\".");
+    }
+  }
+
+  Order order(
+    varCount,
+    ::std::move(gradings),
+    lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+    componentCompareIndex
+  );
+  return ::std::make_pair(
+    MonoMonoid(order),
+    ::std::make_pair(componentsAscendingDesired, doSchreyer)
+  );
+}
+
+template<class E, bool HC, bool SH, bool SO>
+void MonoMonoid<E, HC, SH, SO>::printMonoid(
+  const bool componentsAscendingDesired,
+  ::std::ostream& out
+) const {
+  using MonoMonoidHelper::unchar;
+  typedef typename unchar<Exponent>::type UncharredExponent;
+
+  out << varCount() << '\n'
+      << (isLexBaseOrder() ? "lex" : "revlex")
+      << ' ' << gradingCount() << '\n';
+  MATHICGB_ASSERT(gradings().size() == gradingCount() * varCount());
+  for (VarIndex grading = 0; grading < gradingCount(); ++grading) {
+    if (
+      HasComponent &&
+      grading == gradingCount() - 1 - componentGradingIndex()
+    ) {
+      out << (componentsAscendingDesired ? " component\n" : " revcomponent\n");
+      continue;
+    }
+
+    for (VarIndex var = 0; var < varCount(); ++var) {
+      auto w = gradings()[gradingsOppositeRowIndex(grading, var)];
+      if (!isLexBaseOrder())
+        w = -w;
+      out << ' ' << static_cast<UncharredExponent>(w);
+    }
+    out << '\n';
+  }
+}
+
+template<class E, bool HC, bool SH, bool SO>
+void MonoMonoid<E, HC, SH, SO>::parseM2(::std::istream& in, MonoRef mono) const {
+  using MonoMonoidHelper::unchar;
+  // todo: signal error on exponent overflow
+
+  setIdentity(mono);
+
+  bool sawSome = false;
+  while (true) {
+    const char next = in.peek();
+    if (!sawSome && next == '1') {
+      in.get();
+      break;
+    }
+
+    VarIndex var;
+    const auto letterCount = 'z' - 'a' + 1;
+    if ('a' <= next && next <= 'z')
+      var = next - 'a';
+    else if ('A' <= next && next <= 'Z')
+      var = (next - 'A') + letterCount;
+    else if (sawSome)
+      break;
+    else {
+      mathic::reportError("Could not parse monomial.");
+      return;
+    }
+    MATHICGB_ASSERT(var < 2 * letterCount);
+    if (var >= varCount()) {
+      mathic::reportError("Unknown variable.");
+      return;
+    }
+
+    in.get();
+    auto& exponent = access(mono, exponentsIndexBegin() + var);
+    if (isdigit(in.peek())) {
+      typename unchar<Exponent>::type e;
+      in >> e;
+      exponent = static_cast<Exponent>(e);
+    } else
+      exponent = 1;
+    sawSome = true;
+  }
+
+  if (in.peek() == '<') {
+    if (!HasComponent) {
+      mathic::reportError("Read unexpected < for start of module component\n");
+      return;
+    }
+
+    in.get();
+    if (!isdigit(in.peek())) {
+      mathic::reportError("Component was not integer.");
+      return;
+    }
+    typename unchar<Exponent>::type e;
+    in >> e;
+    access(mono, componentIndex()) = static_cast<Exponent>(e);
+    if (in.peek() != '>') {
+      mathic::reportError("Component < was not matched by >.");
+      return;
+    }
+    in.get();
+  }
+
+  setOrderData(mono);
+  setHash(mono);
+  MATHICGB_ASSERT(debugValid(mono));
+}
+
+template<class E, bool HC, bool SH, bool SO>
+void MonoMonoid<E, HC, SH, SO>::printM2(
+  ConstMonoRef mono,
+  ::std::ostream& out
+) const {
+  using MonoMonoidHelper::unchar;
+  const auto letterCount = 'z' - 'a' + 1;
+
+  bool printedSome = false;
+  for (VarIndex var = 0; var < varCount(); ++var) {
+    if (exponent(mono, var) == 0)
+      continue;
+    char letter;
+    if (var < letterCount)
+      letter = 'a' + static_cast<char>(var);
+    else if (var < 2 * letterCount)
+      letter = 'A' + (static_cast<char>(var) - letterCount);
+    else {
+      mathic::reportError("Too few letters in alphabet to print variable.");
+      return;
+    }
+    printedSome = true;
+    out << letter;
+    if (exponent(mono, var) != 1)
+      out << static_cast<typename unchar<Exponent>::type>(exponent(mono, var));
+  }
+  if (!printedSome)
+    out << '1';
+  if (HasComponent && component(mono) != 0) {
+    out << '<'
+        << static_cast<typename unchar<Exponent>::type>(component(mono))
+        << '>';
+  }
+}
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/MonoOrder.hpp b/src/mathicgb/MonoOrder.hpp
index a85bdb0..a1029c9 100755
--- a/src/mathicgb/MonoOrder.hpp
+++ b/src/mathicgb/MonoOrder.hpp
@@ -1,9 +1,13 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_MONO_ORDER_GUARD
 #define MATHICGB_MONO_ORDER_GUARD
 
 #include <vector>
 #include <algorithm>
 
+MATHICGB_NAMESPACE_BEGIN
+
 /// Class used to describe an monomial order and/or a module monomial
 /// order. Use this class to construct a monoid. The monoid does the
 /// actual comparisons.
@@ -19,7 +23,7 @@ class MonoOrder {
 public:
   typedef W Weight;
   typedef size_t VarIndex;
-  typedef std::vector<Weight> Gradings;
+  typedef ::std::vector<Weight> Gradings;
 
   static const size_t ComponentAfterBaseOrder = static_cast<size_t>(-1);
 
@@ -90,7 +94,7 @@ public:
     const bool schreyering = true
   ):
     mVarCount(varCount),
-    mGradings(std::move(gradings)),
+    mGradings(::std::move(gradings)),
     mBaseOrder(baseOrder),
     mComponentGradingIndex(componentBefore),
     mComponentsAscendingDesired(componentsAscendingDesired),
@@ -170,13 +174,13 @@ private:
     const VarIndex componentBefore
   ) {
     if (componentBefore == ComponentAfterBaseOrder)
-      return std::move(gradings);
+      return ::std::move(gradings);
     MATHICGB_ASSERT(componentBefore <= varCount);
     gradings.resize(gradings.size() + varCount);
     const auto newRow = gradings.begin() + varCount * componentBefore;
-    std::copy_n(newRow, varCount, newRow + varCount);
-    std::fill_n(newRow, varCount, static_cast<Weight>(0));
-    return std::move(gradings);
+    ::std::copy_n(newRow, varCount, newRow + varCount);
+    ::std::fill_n(newRow, varCount, static_cast<Weight>(0));
+    return ::std::move(gradings);
   }
 
   bool debugAssertValid() {
@@ -208,4 +212,5 @@ private:
   const bool mComponentsAscendingDesired;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/MonoProcessor.hpp b/src/mathicgb/MonoProcessor.hpp
index 854d8c2..d160fe8 100755
--- a/src/mathicgb/MonoProcessor.hpp
+++ b/src/mathicgb/MonoProcessor.hpp
@@ -1,131 +1,136 @@
-#ifndef MATHICGB_MONO_PROCESSOR_GUARD
-#define MATHICGB_MONO_PROCESSOR_GUARD
-
-#include "Basis.hpp"
-
-/// Does pre- and post-processing of monomials to implement monomial
-/// orders not directly supported by the monoid. This is so far only
-/// relevant for module monomials.
-///
-/// todo: distinguish monomials from module monomials using two
-/// different monoids.
-template<class Monoid>
-class MonoProcessor;
-
-template<class M>
-class MonoProcessor {
-public:
-  typedef M Monoid;
-  typedef typename Monoid::VarIndex VarIndex;
-  typedef typename Monoid::MonoVector MonoVector;
-  typedef typename Monoid::MonoRef MonoRef;
-  typedef typename Monoid::ConstMonoRef ConstMonoRef;
-  typedef typename Monoid::ConstMonoPtr ConstMonoPtr;
-
-  MonoProcessor(
-    const Monoid& monoid,
-    const bool componentsAscendingDesired,
-    const bool schreyering
-  ):
-    mComponentsAscendingDesired(componentsAscendingDesired),
-    mComponentCount(0),
-    mSchreyering(schreyering),
-    mSchreyerMultipliersMemory(monoid)
-  {}
-
-  void setSchreyering(bool value) {mSchreyering = true;}
-  bool schreyering() const {return mSchreyering;}
-
-  void setSchreyerMultipliers(const Basis& basis) {
-    MonoVector schreyer(monoid());
-    for (size_t gen = 0; gen < basis.size(); ++gen)
-      schreyer.push_back(basis.getPoly(gen)->getLeadMonomial());
-    setSchreyerMultipliers(std::move(schreyer));
-  }
-
-  void setSchreyerMultipliers(MonoVector&& moduleAdjustments) {
-    MATHICGB_ASSERT(moduleAdjustments.monoid() == monoid());
-    MATHICGB_ASSERT(mSchreyerMultipliersMemory.empty() ||
-      mSchreyerMultipliersMemory.size() == componentCount());
-    mSchreyerMultipliersMemory = std::move(moduleAdjustments);
-
-    mSchreyerMultipliers.clear();
-    for (
-      auto it = mSchreyerMultipliersMemory.begin();
-      it != mSchreyerMultipliersMemory.end();
-      ++it
-    ) {
-      // in the absence of a separate monoid for (non-module) monomials,
-      // at least we can check that the component is zero.
-      MATHICGB_ASSERT(this->monoid().component(*it) == 0);
-
-      // todo: there should be a better way of indexing into a
-      // MonoVector.
-      mSchreyerMultipliers.emplace_back((*it).ptr());
-    }
-  }
-    
-
-  void preprocess(MonoRef mono) const {
-    if (hasSchreyerMultipliers())
-      monoid().multiplyInPlace(moduleAdjustment(mono), mono);
-    if (needToReverseComponents())
-      reverseComponent(mono);
-  }
-
-  void postprocess(MonoRef mono) const {
-    if (needToReverseComponents())
-      reverseComponent(mono);
-    if (hasSchreyerMultipliers()) {
-      MATHICGB_ASSERT(monoid().divides(moduleAdjustment(mono), mono));
-      monoid().divideInPlace(moduleAdjustment(mono), mono);
-    }
-  }
-
-  bool processingNeeded() const {
-    return needToReverseComponents() || hasSchreyerMultipliers();
-  }
-
-  bool needToReverseComponents() const {
-    return Monoid::HasComponent &&
-      componentsAscendingDesired() != monoid().componentsAscending();
-  }
-
-  void setComponentsAscendingDesired(bool value) {
-    mComponentsAscendingDesired = value;
-  }
-  bool componentsAscendingDesired() const {return mComponentsAscendingDesired;}
-
-  bool hasSchreyerMultipliers() const {
-    return !mSchreyerMultipliers.empty();
-  }
-
-  void setComponentCount(VarIndex count) {mComponentCount = count;}
-  VarIndex componentCount() const {return mComponentCount;}
-  const Monoid& monoid() const {return mSchreyerMultipliersMemory.monoid();}
-
-private:
-  void operator==(const MonoProcessor&) const; // not available
-
-  void reverseComponent(MonoRef mono) const {
-    const auto component = monoid().component(mono);
-    const auto newComponent = mComponentCount - 1 - component;
-    monoid().setComponent(newComponent, mono);
-  }
-
-  ConstMonoRef moduleAdjustment(ConstMonoRef mono) const {
-    MATHICGB_ASSERT(hasSchreyerMultipliers());
-    const auto component = monoid().component(mono);
-    MATHICGB_ASSERT(component < componentCount());
-    MATHICGB_ASSERT(mSchreyerMultipliers.size() == componentCount());
-    return *mSchreyerMultipliers[component];
-  }
-
-  bool mComponentsAscendingDesired;
-  VarIndex mComponentCount;
-  bool mSchreyering;
-  MonoVector mSchreyerMultipliersMemory;
-  std::vector<ConstMonoPtr> mSchreyerMultipliers;
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_MONO_PROCESSOR_GUARD
+#define MATHICGB_MONO_PROCESSOR_GUARD
+
+#include "Basis.hpp"
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// Does pre- and post-processing of monomials to implement monomial
+/// orders not directly supported by the monoid. This is so far only
+/// relevant for module monomials.
+///
+/// todo: distinguish monomials from module monomials using two
+/// different monoids.
+template<class Monoid>
+class MonoProcessor;
+
+template<class M>
+class MonoProcessor {
+public:
+  typedef M Monoid;
+  typedef typename Monoid::VarIndex VarIndex;
+  typedef typename Monoid::MonoVector MonoVector;
+  typedef typename Monoid::MonoRef MonoRef;
+  typedef typename Monoid::ConstMonoRef ConstMonoRef;
+  typedef typename Monoid::ConstMonoPtr ConstMonoPtr;
+
+  MonoProcessor(
+    const Monoid& monoid,
+    const bool componentsAscendingDesired,
+    const bool schreyering
+  ):
+    mComponentsAscendingDesired(componentsAscendingDesired),
+    mComponentCount(0),
+    mSchreyering(schreyering),
+    mSchreyerMultipliersMemory(monoid)
+  {}
+
+  void setSchreyering(bool value) {mSchreyering = true;}
+  bool schreyering() const {return mSchreyering;}
+
+  void setSchreyerMultipliers(const Basis& basis) {
+    MonoVector schreyer(monoid());
+    for (size_t gen = 0; gen < basis.size(); ++gen)
+      schreyer.push_back(basis.getPoly(gen)->getLeadMonomial());
+    setSchreyerMultipliers(std::move(schreyer));
+  }
+
+  void setSchreyerMultipliers(MonoVector&& moduleAdjustments) {
+    MATHICGB_ASSERT(moduleAdjustments.monoid() == monoid());
+    MATHICGB_ASSERT(mSchreyerMultipliersMemory.empty() ||
+      mSchreyerMultipliersMemory.size() == componentCount());
+    mSchreyerMultipliersMemory = std::move(moduleAdjustments);
+
+    mSchreyerMultipliers.clear();
+    for (
+      auto it = mSchreyerMultipliersMemory.begin();
+      it != mSchreyerMultipliersMemory.end();
+      ++it
+    ) {
+      // in the absence of a separate monoid for (non-module) monomials,
+      // at least we can check that the component is zero.
+      MATHICGB_ASSERT(this->monoid().component(*it) == 0);
+
+      // todo: there should be a better way of indexing into a
+      // MonoVector.
+      mSchreyerMultipliers.emplace_back((*it).ptr());
+    }
+  }
+    
+
+  void preprocess(MonoRef mono) const {
+    if (hasSchreyerMultipliers())
+      monoid().multiplyInPlace(moduleAdjustment(mono), mono);
+    if (needToReverseComponents())
+      reverseComponent(mono);
+  }
+
+  void postprocess(MonoRef mono) const {
+    if (needToReverseComponents())
+      reverseComponent(mono);
+    if (hasSchreyerMultipliers()) {
+      MATHICGB_ASSERT(monoid().divides(moduleAdjustment(mono), mono));
+      monoid().divideInPlace(moduleAdjustment(mono), mono);
+    }
+  }
+
+  bool processingNeeded() const {
+    return needToReverseComponents() || hasSchreyerMultipliers();
+  }
+
+  bool needToReverseComponents() const {
+    return Monoid::HasComponent &&
+      componentsAscendingDesired() != monoid().componentsAscending();
+  }
+
+  void setComponentsAscendingDesired(bool value) {
+    mComponentsAscendingDesired = value;
+  }
+  bool componentsAscendingDesired() const {return mComponentsAscendingDesired;}
+
+  bool hasSchreyerMultipliers() const {
+    return !mSchreyerMultipliers.empty();
+  }
+
+  void setComponentCount(VarIndex count) {mComponentCount = count;}
+  VarIndex componentCount() const {return mComponentCount;}
+  const Monoid& monoid() const {return mSchreyerMultipliersMemory.monoid();}
+
+private:
+  void operator==(const MonoProcessor&) const; // not available
+
+  void reverseComponent(MonoRef mono) const {
+    const auto component = monoid().component(mono);
+    const auto newComponent = mComponentCount - 1 - component;
+    monoid().setComponent(newComponent, mono);
+  }
+
+  ConstMonoRef moduleAdjustment(ConstMonoRef mono) const {
+    MATHICGB_ASSERT(hasSchreyerMultipliers());
+    const auto component = monoid().component(mono);
+    MATHICGB_ASSERT(component < componentCount());
+    MATHICGB_ASSERT(mSchreyerMultipliers.size() == componentCount());
+    return *mSchreyerMultipliers[component];
+  }
+
+  bool mComponentsAscendingDesired;
+  VarIndex mComponentCount;
+  bool mSchreyering;
+  MonoVector mSchreyerMultipliersMemory;
+  std::vector<ConstMonoPtr> mSchreyerMultipliers;
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/MonomialHashTable.hpp b/src/mathicgb/MonomialHashTable.hpp
index 1d2f33d..28fe9af 100755
--- a/src/mathicgb/MonomialHashTable.hpp
+++ b/src/mathicgb/MonomialHashTable.hpp
@@ -1,12 +1,13 @@
 // MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
 // NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
-
-#ifndef _MonomialHashTable_h_
-#define _MonomialHashTable_h_
+#ifndef MATHICGB_MONOMIAL_HASH_TABLE_GUARD
+#define MATHICGB_MONOMIAL_HASH_TABLE_GUARD
 
 #include "ChainedHashTable.hpp"
 #include "PolyRing.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 class MonomialHashControl
 {
 public:
@@ -82,9 +83,6 @@ private:
   memt::Arena mMonomialPool;
   MonomialHashTableBasic H_;
 };
-#endif
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/MonomialMap.hpp b/src/mathicgb/MonomialMap.hpp
index 6975c43..7787cd4 100755
--- a/src/mathicgb/MonomialMap.hpp
+++ b/src/mathicgb/MonomialMap.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_MONOMIAL_MAP_GUARD
 #define MATHICGB_MONOMIAL_MAP_GUARD
 
@@ -10,6 +12,8 @@
 #include <vector>
 #include <algorithm>
 
+MATHICGB_NAMESPACE_BEGIN
+
 /// A concurrent hash map from monomials to T. This map can resize itself
 /// if there are too few buckets compared to entries.
 ///
@@ -44,10 +48,10 @@ public:
   MonomialMap(const PolyRing& ring):
     mMap(new FixedSizeMap(InitialBucketCount, ring)),
     mCapacityUntilGrowth
-    (maxEntries(mMap.load(std::memory_order_relaxed)->bucketCount())),
+    (maxEntries(mMap.load(::std::memory_order_relaxed)->bucketCount())),
     mRing(ring)
   {
-    // We can load mMap as std::memory_order_relaxed because we just stored it
+    // We can load mMap as ::std::memory_order_relaxed because we just stored it
     // and the constructor cannot run concurrently.
   }
 
@@ -77,9 +81,9 @@ public:
   class Reader {
   public:
     Reader(const MonomialMap<T>& map):
-      mMap(*map.mMap.load(std::memory_order_seq_cst))
+      mMap(*map.mMap.load(::std::memory_order_seq_cst))
     {
-      // We grab the hash table pointer with std::memory_order_seq_cst in order
+      // We grab the hash table pointer with ::std::memory_order_seq_cst in order
       // to force a CPU cache flush - in this way we are more likely to get an
       // up to date value.
     }
@@ -88,14 +92,14 @@ public:
     /// inserted. Also returns the internal monomial that matches mono if such
     /// a monomial exists. Misses can be spurious! Read the comments on the parent
     /// class.
-    std::pair<const mapped_type*, ConstMonomial>
+    ::std::pair<const mapped_type*, ConstMonomial>
     find(const_monomial mono) const {
       return mMap.find(mono);
     }
 
     // As find but looks for the product of a and b and also returns the
     // monomal that is the product.
-    std::pair<const mapped_type*, ConstMonomial> findProduct(
+    ::std::pair<const mapped_type*, ConstMonomial> findProduct(
       const const_monomial a,
       const const_monomial b
     ) const {
@@ -106,7 +110,7 @@ public:
     /// simultaneously. The purpose of this is similar to that of unrolling a
     /// loop.
     MATHICGB_INLINE
-    std::pair<const mapped_type*, const mapped_type*> findTwoProducts(
+    ::std::pair<const mapped_type*, const mapped_type*> findTwoProducts(
       const const_monomial a1,
       const const_monomial a2,
       const const_monomial b
@@ -137,13 +141,13 @@ public:
   /// equal value.second if an insertion was not performed - unless the
   /// inserted value equals the already present value. p.first.second is an
   /// internal monomial that equals value.first.
-  std::pair<std::pair<const mapped_type*, ConstMonomial>, bool>
+  ::std::pair< ::std::pair<const mapped_type*, ConstMonomial>, bool>
   insert(const value_type& value) {
     const mgb::tbb::mutex::scoped_lock lockGuard(mInsertionMutex);
 
-    // We can load mMap as std::memory_order_relaxed because we have already
+    // We can load mMap as ::std::memory_order_relaxed because we have already
     // synchronized with all other mutators by locking mInsertionMutex;
-    auto map = mMap.load(std::memory_order_relaxed);
+    auto map = mMap.load(::std::memory_order_relaxed);
 
     // this is a loop since it is possible to set the growth factor and
     // the initial size so low that several rounds are required. This should
@@ -152,21 +156,21 @@ public:
     while (mCapacityUntilGrowth == 0) {
       // Resize the table by making a bigger one and using that instead.
       if (map->bucketCount() > // check overflow
-        std::numeric_limits<size_t>::max() / GrowthFactor)
+        ::std::numeric_limits<size_t>::max() / GrowthFactor)
       {
-        throw std::bad_alloc();
+        throw ::std::bad_alloc();
       }
       const size_t newBucketCount = map->bucketCount() * GrowthFactor;
       auto nextMap =
-        make_unique<FixedSizeMap>(newBucketCount, std::move(*map));
+        make_unique<FixedSizeMap>(newBucketCount, ::std::move(*map));
       mOldMaps.emplace_back(map);
       mCapacityUntilGrowth =
         maxEntries(nextMap->bucketCount()) - maxEntries(map->bucketCount());
 
-      // Store with std::memory_order_seq_cst to force a memory flush so that
+      // Store with ::std::memory_order_seq_cst to force a memory flush so that
       // readers see the new table as soon as possible.
       map = nextMap.release();
-      mMap.store(map, std::memory_order_seq_cst);
+      mMap.store(map, ::std::memory_order_seq_cst);
     }
     MATHICGB_ASSERT(mCapacityUntilGrowth > 0);
 
@@ -180,9 +184,9 @@ public:
   /// call too much. The count may have 
   size_t entryCount() const {
     const mgb::tbb::mutex::scoped_lock lockGuard(mInsertionMutex);
-    // We can load with std::memory_order_relaxed because we are holding the
+    // We can load with ::std::memory_order_relaxed because we are holding the
     // lock.
-    auto& map = *mMap.load(std::memory_order_relaxed);
+    auto& map = *mMap.load(::std::memory_order_relaxed);
     return maxEntries(map.bucketCount()) - mCapacityUntilGrowth;
   }
 
@@ -207,7 +211,8 @@ private:
   /// keep these around as we have no way to determine if there are still
   /// readers looking at them. This could be changed at the cost of
   /// more overhead in the Reader constructor and destructor.
-  std::vector<std::unique_ptr<FixedSizeMap>> mOldMaps;
+  ::std::vector< ::std::unique_ptr<FixedSizeMap>> mOldMaps;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/NonCopyable.hpp b/src/mathicgb/NonCopyable.hpp
index e64dfa0..db95a00 100755
--- a/src/mathicgb/NonCopyable.hpp
+++ b/src/mathicgb/NonCopyable.hpp
@@ -1,22 +1,27 @@
-#ifndef MATHICGB_NON_COPYABLE_GUARD
-#define MATHICGB_NON_COPYABLE_GUARD
-
-/// Derive from this class to disable the compiler-generated copy
-/// constructor and assignment. T should be the class that is deriving
-/// from NonCopyable.
-///
-/// The purpose of the template parameter is to avoid any chance of
-/// getting a diamond-graph inheritance graph. Diamond graphs can lead
-/// to runtime overhead.
-template<class T>
-class NonCopyable {
-public:
-  NonCopyable() {}
-  NonCopyable(NonCopyable&&) {} // still movable.
-
-private:
-  NonCopyable(const NonCopyable&); // unavailable
-  void operator=(const NonCopyable&); // unavailable
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_NON_COPYABLE_GUARD
+#define MATHICGB_NON_COPYABLE_GUARD
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// Derive from this class to disable the compiler-generated copy
+/// constructor and assignment. T should be the class that is deriving
+/// from NonCopyable.
+///
+/// The purpose of the template parameter is to avoid any chance of
+/// getting a diamond-graph inheritance graph. Diamond graphs can lead
+/// to runtime overhead.
+template<class T>
+class NonCopyable {
+public:
+  NonCopyable() {}
+  NonCopyable(NonCopyable&&) {} // still movable.
+
+private:
+  NonCopyable(const NonCopyable&); // unavailable
+  void operator=(const NonCopyable&); // unavailable
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/PairTriangle.cpp b/src/mathicgb/PairTriangle.cpp
index 056ad7f..715169c 100755
--- a/src/mathicgb/PairTriangle.cpp
+++ b/src/mathicgb/PairTriangle.cpp
@@ -1,9 +1,13 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "PairTriangle.hpp"
 
 #include <limits>
 #include <stdexcept>
 
+MATHICGB_NAMESPACE_BEGIN
+
 PairTriangle::PairTriangle(const PolyRing& ring, size_t queueType):
   mColumnCount(0),
   mRing(ring),
@@ -104,3 +108,5 @@ std::pair<size_t, size_t> PairTriangle::topPair() const {
 const_monomial PairTriangle::topOrderBy() const {
   return mPairQueue.topPairData();
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PairTriangle.hpp b/src/mathicgb/PairTriangle.hpp
index 20afc47..29a2aca 100755
--- a/src/mathicgb/PairTriangle.hpp
+++ b/src/mathicgb/PairTriangle.hpp
@@ -1,10 +1,14 @@
-#ifndef _pair_triangle_h
-#define _pair_triangle_h
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_PAIR_TRIANGLE_GUARD
+#define MATHICGB_PAIR_TRIANGLE_GUARD
 
-#include <memtailor.h>
-#include <mathic.h>
 #include "PolyRing.hpp"
 #include "SigSPairQueue.hpp"
+#include <memtailor.h>
+#include <mathic.h>
+
+MATHICGB_NAMESPACE_BEGIN
 
 /*typedef unsigned short SmallIndex;
 typedef unsigned int BigIndex;
@@ -101,23 +105,30 @@ private:
   };
   mathic::PairQueue<PC> mPairQueue;
   friend void mathic::PairQueueNamespace::constructPairData<PC>(void*,Index,Index,PC&);
-  friend void mathic::PairQueueNamespace::destructPairData<PC>(monomial*,Index,Index, PC&);
+  friend void mathic::PairQueueNamespace::destructPairData<PC>(PC::PairData*,Index,Index, PC&);
 };
 
+MATHICGB_NAMESPACE_END
+
 namespace mathic {
   namespace PairQueueNamespace {
     template<>
-    inline void constructPairData<PairTriangle::PC>
-    (void* memory, Index col, Index row, PairTriangle::PC& conf) {
+    inline void constructPairData<mgb::PairTriangle::PC>
+    (void* memory, Index col, Index row, mgb::PairTriangle::PC& conf) {
       MATHICGB_ASSERT(memory != 0);
       MATHICGB_ASSERT(col > row);
-      monomial* pd = new (memory) monomial(conf.allocPairData());
+      auto pd = new (memory)
+        mgb::PairTriangle::PC::PairData(conf.allocPairData());
       conf.computePairData(col, row, *pd);
     }
     
     template<>
-    inline void destructPairData
-    (monomial* pd, Index col, Index row, PairTriangle::PC& conf) {
+    inline void destructPairData<mgb::PairTriangle::PC>(
+      mgb::PairTriangle::PC::PairData* pd,
+      Index col,
+      Index row,
+      mgb::PairTriangle::PC& conf
+    ) {
       MATHICGB_ASSERT(pd != 0);
       MATHICGB_ASSERT(col > row);
       conf.freePairData(*pd);
diff --git a/src/mathicgb/Poly.cpp b/src/mathicgb/Poly.cpp
index 5a8dcf8..80939b3 100755
--- a/src/mathicgb/Poly.cpp
+++ b/src/mathicgb/Poly.cpp
@@ -1,11 +1,14 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "Poly.hpp"
+
 #include <ostream>
 #include <iostream>
 #include <algorithm>
 
+MATHICGB_NAMESPACE_BEGIN
+
 // Format for input/output:
 //  #terms term1 term2 ...
 //  each term: coeff monom
@@ -388,8 +391,4 @@ bool Poly::termsAreInDescendingOrder() const {
   return true;
 }
 
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/Poly.hpp b/src/mathicgb/Poly.hpp
index 059ccf0..484cfc4 100755
--- a/src/mathicgb/Poly.hpp
+++ b/src/mathicgb/Poly.hpp
@@ -1,7 +1,7 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _poly_h_
-#define _poly_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_POLY_GUARD
+#define MATHICGB_POLY_GUARD
 
 #include "PolyRing.hpp"
 #include <vector>
@@ -10,31 +10,33 @@
 #include <cstdio>
 #include <iterator>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class Poly {
 public:
   Poly(const PolyRing& ring) : R(&ring) {MATHICGB_ASSERT(R != 0);}
 
-  void parse(std::istream &i); // reads into this, sorts terms
-  void parseDoNotOrder(std::istream &i); // reads into this, does not sort terms
+  void parse(::std::istream &i); // reads into this, sorts terms
+  void parseDoNotOrder(::std::istream &i); // reads into this, does not sort terms
   void display(FILE* file, bool printComponent = true) const;
-  void display(std::ostream& out, bool printComponent = true) const;
+  void display(::std::ostream& out, bool printComponent = true) const;
   void see(bool print_comp) const;
 
   class iterator {
     // only for const objects...
     size_t monsize;
-    std::vector<coefficient>::iterator ic;
-    std::vector<exponent>::iterator im;
+    ::std::vector<coefficient>::iterator ic;
+    ::std::vector<exponent>::iterator im;
     friend class Poly;
 
     iterator(Poly& f) : monsize(f.getRing()->maxMonomialSize()), ic(f.coeffs.begin()), im(f.monoms.begin()) {}
     iterator(Poly& f,int) : ic(f.coeffs.end()), im() {}
   public:
-    typedef std::random_access_iterator_tag iterator_category;
-    typedef std::pair<coefficient, const const_monomial> value_type;
+    typedef ::std::random_access_iterator_tag iterator_category;
+    typedef ::std::pair<coefficient, const const_monomial> value_type;
     typedef ptrdiff_t difference_type;
     typedef value_type* pointer; // todo: is this OK?
-    typedef std::pair<coefficient&, const const_monomial> reference;
+    typedef ::std::pair<coefficient&, const const_monomial> reference;
 
     iterator() {}
     iterator operator++() { ++ic; im += monsize; return *this; }
@@ -44,25 +46,25 @@ public:
     friend bool operator==(const iterator &a, const iterator &b);
     friend bool operator!=(const iterator &a, const iterator &b);
     reference operator*() const {
-      return std::pair<coefficient&, monomial>(getCoefficient(), getMonomial());
+      return ::std::pair<coefficient&, monomial>(getCoefficient(), getMonomial());
     }
   };
 
   class const_iterator {
     // only for const objects...
     size_t monsize;
-    std::vector<coefficient>::const_iterator ic;
-    std::vector<exponent>::const_iterator im;
+    ::std::vector<coefficient>::const_iterator ic;
+    ::std::vector<exponent>::const_iterator im;
     friend class Poly;
 
     const_iterator(const Poly& f) : monsize(f.getRing()->maxMonomialSize()), ic(f.coeffs.begin()), im(f.monoms.begin()) {}
     const_iterator(const Poly& f,int) : ic(f.coeffs.end()), im() {}
   public:
-    typedef std::random_access_iterator_tag iterator_category;
-    typedef std::pair<const coefficient, const const_monomial> value_type;
+    typedef ::std::random_access_iterator_tag iterator_category;
+    typedef ::std::pair<const coefficient, const const_monomial> value_type;
     typedef ptrdiff_t difference_type;
     typedef value_type* pointer; // todo: is this OK?
-    typedef std::pair<const coefficient&, const const_monomial> reference;
+    typedef ::std::pair<const coefficient&, const const_monomial> reference;
 
     const_iterator() {}
     const_iterator operator++() { ++ic; im += monsize; return *this; }
@@ -72,7 +74,7 @@ public:
     friend bool operator==(const const_iterator &a, const const_iterator &b);
     friend bool operator!=(const const_iterator &a, const const_iterator &b);
     const value_type operator*() const {
-      return std::pair<coefficient, const_monomial>
+      return ::std::pair<coefficient, const_monomial>
         (getCoefficient(), getMonomial());
     }
   };
@@ -150,11 +152,11 @@ public:
 
 private:
   const PolyRing *R;
-  std::vector<coefficient> coeffs;
-  std::vector<exponent> monoms;
+  ::std::vector<coefficient> coeffs;
+  ::std::vector<exponent> monoms;
 };
 
-std::ostream& operator<<(std::ostream& out, const Poly& p);
+::std::ostream& operator<<(::std::ostream& out, const Poly& p);
 
 inline bool operator==(const Poly::iterator &a, const Poly::iterator &b)
 {
@@ -192,10 +194,5 @@ inline void Poly::appendTerm(coefficient a, PolyRing::Monoid::ConstMonoRef m) {
   monoid.copy(m, *PolyRing::Monoid::MonoPtr(monoms.data() + offset));
 }
 
-
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/PolyBasis.cpp b/src/mathicgb/PolyBasis.cpp
index a7f2be5..e2cf091 100755
--- a/src/mathicgb/PolyBasis.cpp
+++ b/src/mathicgb/PolyBasis.cpp
@@ -1,9 +1,13 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
-#include "Basis.hpp"
 #include "PolyBasis.hpp"
 
+#include "Basis.hpp"
 #include "DivisorLookup.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 PolyBasis::PolyBasis(
   const PolyRing& ring,
   std::unique_ptr<DivisorLookup> divisorLookup
@@ -189,3 +193,5 @@ PolyBasis::Entry::Entry():
   usedAsReducerCount(0),
   possibleReducerCount(0),
   nonSignatureReducerCount(0) {}
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PolyBasis.hpp b/src/mathicgb/PolyBasis.hpp
index df8577c..a7d4d3a 100755
--- a/src/mathicgb/PolyBasis.hpp
+++ b/src/mathicgb/PolyBasis.hpp
@@ -1,11 +1,15 @@
-#ifndef _poly_basis_h_
-#define _poly_basis_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_POLY_BASIS_GUARD
+#define MATHICGB_POLY_BASIS_GUARD
 
 #include "Poly.hpp"
 #include "DivisorLookup.hpp"
 #include <vector>
 #include <memory>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class PolyRing;
 class Basis;
 
@@ -16,19 +20,19 @@ public:
   // Ring must live for as long as this object.
   PolyBasis(
     const PolyRing& ring,
-    std::unique_ptr<DivisorLookup> divisorLookup
+    ::std::unique_ptr<DivisorLookup> divisorLookup
   );
 
   // Deletes the Poly's stored in the basis.
   ~PolyBasis();
 
   // Returns the initial monomial basis of the basis.
-  std::unique_ptr<Basis> initialIdeal() const;
+  ::std::unique_ptr<Basis> initialIdeal() const;
 
   // Inserts a polynomial into the basis at index size().
   // Lead monomials must be unique among basis elements.
   // So the index is size() - 1 afterwards since size() will increase by 1.
-  void insert(std::unique_ptr<Poly> poly);
+  void insert(::std::unique_ptr<Poly> poly);
 
   // Returns the index of a basis element whose lead term divides mon.
   // Returns -1 if there is no such basis element.
@@ -44,7 +48,7 @@ public:
   // Replaces basis element at index with the given new value. The lead
   // term of the new polynomial must be the same as the previous one.
   // This is useful for auto-tail-reduction.
-  void replaceSameLeadTerm(size_t index, std::unique_ptr<Poly> newValue) {
+  void replaceSameLeadTerm(size_t index, ::std::unique_ptr<Poly> newValue) {
     MATHICGB_ASSERT(index < size());
     MATHICGB_ASSERT(!retired(index));
     MATHICGB_ASSERT(newValue.get() != 0);
@@ -72,12 +76,12 @@ public:
 
   // Retires the basis element at index, which frees the memory associated
   // to it, including the basis element polynomial, and marks it as retired. 
-  std::unique_ptr<Poly> retire(size_t index);
+  ::std::unique_ptr<Poly> retire(size_t index);
 
   /// Returns an basis containing all non-retired basis elements and
   /// retires all those basis elements. The point of the simultaneous
   /// retirement is that this way no polynomials need be copied.
-  std::unique_ptr<Basis> toBasisAndRetireAll();
+  ::std::unique_ptr<Basis> toBasisAndRetireAll();
 
   // Returns true of the basis element at index has been retired.
   bool retired(size_t index) const {
@@ -210,13 +214,14 @@ private:
     mutable unsigned long long possibleReducerCount;
     mutable unsigned long long nonSignatureReducerCount;
   };
-  typedef std::vector<Entry> EntryCont;
+  typedef ::std::vector<Entry> EntryCont;
   typedef EntryCont::iterator EntryIter;
   typedef EntryCont::const_iterator EntryCIter;
 
   const PolyRing& mRing;
-  std::unique_ptr<DivisorLookup> mDivisorLookup;
-  std::vector<Entry> mEntries;
+  ::std::unique_ptr<DivisorLookup> mDivisorLookup;
+  ::std::vector<Entry> mEntries;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/PolyGeoBucket.cpp b/src/mathicgb/PolyGeoBucket.cpp
index 6538c13..10d95a0 100755
--- a/src/mathicgb/PolyGeoBucket.cpp
+++ b/src/mathicgb/PolyGeoBucket.cpp
@@ -1,9 +1,12 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "PolyGeoBucket.hpp"
+
 #include <mathic.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 const size_t heap_size[GEOHEAP_SIZE] = {4, 16, 64, 256, 1024, 4096,
                                16384, 65536, 262144, 1048576, 4194304,
                                16777216, 67108864, 268435456,
@@ -259,7 +262,4 @@ void PolyGeoBucket::dump() const
 {
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PolyGeoBucket.hpp b/src/mathicgb/PolyGeoBucket.hpp
index ea95cab..97de1e3 100755
--- a/src/mathicgb/PolyGeoBucket.hpp
+++ b/src/mathicgb/PolyGeoBucket.hpp
@@ -1,10 +1,13 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _polyGeoBucket_h_
-#define _polyGeoBucket_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_POLY_GEO_BUCKET_GUARD
+#define MATHICGB_POLY_GEO_BUCKET_GUARD
 
 #include "TypicalReducer.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
+/// @todo: shouldn't be a macro
 #define GEOHEAP_SIZE 15
 
 class PolyGeoBucket : public TypicalReducer {
@@ -51,9 +54,5 @@ private:
 
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/PolyHashReducer.cpp b/src/mathicgb/PolyHashReducer.cpp
index 3e97193..9164bc5 100755
--- a/src/mathicgb/PolyHashReducer.cpp
+++ b/src/mathicgb/PolyHashReducer.cpp
@@ -1,8 +1,10 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "PolyHashReducer.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 PolyHashReducer::PolyHashReducer(const PolyRing *R0):
   R_(R0), H_(R0,15)
 {
@@ -164,7 +166,4 @@ void PolyHashReducer::dump() const
   H_.dump(0);
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PolyHashReducer.hpp b/src/mathicgb/PolyHashReducer.hpp
index 749be06..d7c5e54 100755
--- a/src/mathicgb/PolyHashReducer.hpp
+++ b/src/mathicgb/PolyHashReducer.hpp
@@ -1,11 +1,13 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _polyHashReducer_h_
-#define _polyHashReducer_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_POLY_HASH_REDUCER_GUARD
+#define MATHICGB_POLY_HASH_REDUCER_GUARD
 
 #include "TypicalReducer.hpp"
 #include "PolyHashTable.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 class PolyHashReducer : public TypicalReducer {
 public:
   PolyHashReducer(const PolyRing *R);
@@ -48,9 +50,5 @@ private:
   PolyHashTable H_;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/PolyHashTable.cpp b/src/mathicgb/PolyHashTable.cpp
index 075ea25..9df610d 100755
--- a/src/mathicgb/PolyHashTable.cpp
+++ b/src/mathicgb/PolyHashTable.cpp
@@ -1,4 +1,5 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "PolyHashTable.hpp"
 
@@ -6,6 +7,7 @@
 #include <iostream>
 #include <cmath>
 
+MATHICGB_NAMESPACE_BEGIN
 
 const double PolyHashTable::threshold = 0.1;
 const bool AlwaysInsertAtEnd = true;
@@ -455,10 +457,6 @@ void PolyHashTable::dump(int level) const
       f.display(std::cout);
       std::cout << std::endl;
     }
-
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PolyHashTable.hpp b/src/mathicgb/PolyHashTable.hpp
old mode 100644
new mode 100755
index 3119be8..d5801f0
--- a/src/mathicgb/PolyHashTable.hpp
+++ b/src/mathicgb/PolyHashTable.hpp
@@ -1,14 +1,15 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_POLY_HASH_TABLE_GUARD
+#define MATHICGB_POLY_HASH_TABLE_GUARD
 
-#ifndef _PolyHashTable_h_
-#define _PolyHashTable_h_
-
-#include <vector>
-
-#include <memtailor.h>
 #include "PolyRing.hpp"
 #include "Poly.hpp"
 #include <utility>
+#include <memtailor.h>
+#include <vector>
+
+MATHICGB_NAMESPACE_BEGIN
 
 // The hash table is a map:  monomial => coeff
 // Operations required on monomials:
@@ -137,11 +138,5 @@ protected:
   size_t mMonomialSize;
 };
 
-
-
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/PolyHeap.cpp b/src/mathicgb/PolyHeap.cpp
index 3d5f3af..ccf8c45 100755
--- a/src/mathicgb/PolyHeap.cpp
+++ b/src/mathicgb/PolyHeap.cpp
@@ -1,10 +1,13 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "PolyHeap.hpp"
 
 #include <iostream>
 #include <algorithm>
 
+MATHICGB_NAMESPACE_BEGIN
+
 size_t PolyHeap::stats_static_n_compares = 0;
 
 PolyHeap::PolyHeap(const PolyRing *R_):
@@ -173,7 +176,4 @@ void PolyHeap::dump() const
     }
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PolyHeap.hpp b/src/mathicgb/PolyHeap.hpp
index dbfdebd..a17c32e 100755
--- a/src/mathicgb/PolyHeap.hpp
+++ b/src/mathicgb/PolyHeap.hpp
@@ -1,10 +1,12 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _polyHeap_h_
-#define _polyHeap_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_POLY_HEAP_GUARD
+#define MATHICGB_POLY_HEAP_GUARD
 
 #include "TypicalReducer.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 struct heap_term {
   monomial actual;  // multiplier * *first
   const_term multiplier;
@@ -66,9 +68,5 @@ inline bool heapCompareFcn::operator()(heap_term &a, heap_term &b)
   return R->monomialLT(a.actual, b.actual);
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/PolyReducer.cpp b/src/mathicgb/PolyReducer.cpp
index 50a189d..5f37ae4 100755
--- a/src/mathicgb/PolyReducer.cpp
+++ b/src/mathicgb/PolyReducer.cpp
@@ -1,7 +1,10 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "PolyReducer.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 PolyReducer::PolyReducer(const PolyRing *R0):
   R(R0), mMemUsage(0)
 {
@@ -108,7 +111,4 @@ size_t PolyReducer::getMemoryUse() const {
   return mMemUsage;
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PolyReducer.hpp b/src/mathicgb/PolyReducer.hpp
index 0de2c5d..d09450c 100755
--- a/src/mathicgb/PolyReducer.hpp
+++ b/src/mathicgb/PolyReducer.hpp
@@ -1,10 +1,12 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _polyReducer_h_
-#define _polyReducer_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_POLY_REDUCER_GUARD
+#define MATHICGB_POLY_REDUCER_GUARD
 
 #include "TypicalReducer.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 class PolyReducer : public TypicalReducer {
 public:
   PolyReducer(const PolyRing *R);
@@ -37,9 +39,5 @@ private:
   size_t mMemUsage;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/PolyRing.cpp b/src/mathicgb/PolyRing.cpp
index 1c50fd1..0c7e398 100755
--- a/src/mathicgb/PolyRing.cpp
+++ b/src/mathicgb/PolyRing.cpp
@@ -1,4 +1,5 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "PolyRing.hpp"
 
@@ -11,6 +12,8 @@
 #include <cstdlib>
 #include <limits>
 
+MATHICGB_NAMESPACE_BEGIN
+
 PolyRing::PolyRing(const Field& field, Monoid&& monoid):
   mField(field), mMonoid(std::move(monoid))
 {}
@@ -244,7 +247,4 @@ void PolyRing::write(std::ostream &o, bool componentIncreasingDesired) const
   monoid().printMonoid(componentIncreasingDesired, o);
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index 4b5e3f5..3be2658 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -1,7 +1,7 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _polyRing_h_
-#define _polyRing_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_POLY_RING_GUARD
+#define MATHICGB_POLY_RING_GUARD
 
 #include "MonoMonoid.hpp"
 #include "PrimeField.hpp"
@@ -13,6 +13,7 @@
 #include <cstring>
 #include <limits>
 
+MATHICGB_NAMESPACE_BEGIN
 
 #define LT (-1)
 #define EQ 0
@@ -21,8 +22,8 @@
 
 template<class T>
 PrimeField<
-  typename std::make_unsigned<
-    typename std::remove_reference<T>::type
+  typename ::std::make_unsigned<
+    typename ::std::remove_reference<T>::type
   >::type
 > makeField(T charac) {
   return charac;
@@ -152,7 +153,7 @@ public:
   Monomial(exponent *val) : ConstMonomial(val) {}
 
   void swap(Monomial& monomial) {
-    std::swap(mValue, monomial.mValue);
+    ::std::swap(mValue, monomial.mValue);
   }
 
   exponent * unsafeGetRepresentation() { return const_cast<exponent *>(mValue); }
@@ -204,7 +205,7 @@ public:
     coefficient charac,
     int nvars,
     bool lexBaseOrder,
-    std::vector<exponent>&& weights
+    ::std::vector<exponent>&& weights
   );
   PolyRing(const Field& field, Monoid&& monoid);
 
@@ -216,11 +217,11 @@ public:
   coefficient charac() const { return mField.charac(); }
   size_t getNumVars() const { return varCount();}
   size_t varCount() const {return monoid().varCount();}
-  //       const std::vector<int> &degs,
-  //       const std::string &monorder);
+  //       const ::std::vector<int> &degs,
+  //       const ::std::string &monorder);
 
-  static std::pair<PolyRing*, std::pair<bool, bool>> read(std::istream &i);
-  void write(std::ostream &o, bool componentIncreasingDesired) const;
+  static ::std::pair<PolyRing*, ::std::pair<bool, bool>> read(::std::istream &i);
+  void write(::std::ostream &o, bool componentIncreasingDesired) const;
   // Format for ring
   //   <char> <mNumVars> <deg1> ... <deg_n> <monorder>
 
@@ -233,7 +234,7 @@ public:
     // fill with value that do not make sense to catch bugs in debug
     // mode. The maximum value of setting all bits increases the
     // chances of getting an assert.
-    std::fill_n(reinterpret_cast<char*>(ptr), maxMonomialByteSize(),
+    ::std::fill_n(reinterpret_cast<char*>(ptr), maxMonomialByteSize(),
                 ~static_cast<char>(0));
 #endif
     return ptr;
@@ -255,7 +256,7 @@ public:
     // fill with value that do not make sense to catch bugs in debug
     // mode. The maximum value of setting all bits increases the
     // chances of getting an assert.
-    std::fill_n(reinterpret_cast<char*>(ptr), maxMonomialByteSize(),
+    ::std::fill_n(reinterpret_cast<char*>(ptr), maxMonomialByteSize(),
                 ~static_cast<char>(0));
 #endif
     return ptr;
@@ -458,10 +459,10 @@ public:
     ConstMonomial smaller1,
     ConstMonomial smaller2) const;
 
-  void monomialParse(std::istream& i, 
+  void monomialParse(::std::istream& i, 
                      Monomial& result) const;
 
-  void monomialDisplay(std::ostream& o, 
+  void monomialDisplay(::std::ostream& o, 
                        ConstMonomial a, 
                        bool print_comp=true, 
                        bool print_one=true) const;
@@ -470,7 +471,7 @@ public:
                        bool printComponent = true, 
                        bool printOne = true) const;
 
-  void printMonomialFrobbyM2Format(std::ostream& out, ConstMonomial m) const;
+  void printMonomialFrobbyM2Format(::std::ostream& out, ConstMonomial m) const;
 
   ///////////////////////////////////////////
   ///////////////////////////////////////////
@@ -699,9 +700,5 @@ inline bool PolyRing::monomialHasAmpleCapacity(ConstMonomial mono) const {
   return monoid().hasAmpleCapacity(mono);
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/PrimeField.hpp b/src/mathicgb/PrimeField.hpp
index 4dcf4f3..1be98c5 100755
--- a/src/mathicgb/PrimeField.hpp
+++ b/src/mathicgb/PrimeField.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_PRIME_FIELD_GUARD
 #define MATHICGB_PRIME_FIELD_GUARD
 
@@ -5,9 +7,11 @@
 #include <type_traits>
 #include <ostream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 /// Implements arithmetic in a prime field. T must be an unsigned integer type
 /// that is used to store the elements of the field. The characteristic of the
-/// field must be a prime not exceeding std::numeric_limits<T>::max().
+/// field must be a prime not exceeding ::std::numeric_limits<T>::max().
 template<class T>
 class PrimeField {
 public:
@@ -15,8 +19,8 @@ public:
 
   class Element {
   public:
-    static_assert(!std::numeric_limits<T>::is_signed, "");
-    static_assert(std::numeric_limits<T>::is_integer, "");
+    static_assert(!::std::numeric_limits<T>::is_signed, "");
+    static_assert(::std::numeric_limits<T>::is_integer, "");
 
     Element(const Element& e): mValue(e.value()) {}
 
@@ -51,19 +55,19 @@ public:
   /// Assumes that i is in the range [0;charac()).
   template<class Integer>
   Element toElementInRange(Integer&& i) const {
-    typedef typename std::remove_reference<Integer>::type NoRefInteger;
-    static_assert(std::numeric_limits<NoRefInteger>::is_integer, "");
+    typedef typename ::std::remove_reference<Integer>::type NoRefInteger;
+    static_assert(::std::numeric_limits<NoRefInteger>::is_integer, "");
 
     MATHICGB_ASSERT(0 <= i);
-    typedef typename std::make_unsigned<NoRefInteger>::type Unsigned;
+    typedef typename ::std::make_unsigned<NoRefInteger>::type Unsigned;
     MATHICGB_ASSERT(static_cast<Unsigned>(i) < charac());
     return Element(i);
   }
 
   template<class Integer>
   Element toElement(Integer&& i) const {
-    typedef typename std::remove_reference<Integer>::type NoRefInteger;
-    static_assert(std::numeric_limits<NoRefInteger>::is_integer, "");
+    typedef typename ::std::remove_reference<Integer>::type NoRefInteger;
+    static_assert(::std::numeric_limits<NoRefInteger>::is_integer, "");
 
     // We need to take the modulus of i to put it into the range [0;charac()).
     // That is more tricky to get right than it might seem.
@@ -74,11 +78,11 @@ public:
     // converted to a signed integer since it might not be representable that
     // way.
     //
-    // If Integer is signed and i is std::numeric_limits<Integer>::min() then
+    // If Integer is signed and i is ::std::numeric_limits<Integer>::min() then
     // it is undefined behavior to evaluate the expression -i since -i is not
     // representable, leading to a signed overflow. So we have to cast to
     // unsigned before doing the minus.
-    typedef typename std::make_unsigned<NoRefInteger>::type Unsigned;
+    typedef typename ::std::make_unsigned<NoRefInteger>::type Unsigned;
     if (i < 0) {
       // Negate i to get a positive number, then negate again to cancel out
       // the first negation. The first cast to unsigned is to avoid
@@ -223,12 +227,13 @@ auto PrimeField<T>::inverse(const Element elementA) const -> Element {
 
 
 template<class T>
-std::ostream& operator<<(
-  std::ostream& out,
+::std::ostream& operator<<(
+  ::std::ostream& out,
   typename PrimeField<T>::Element e
 ) {
   out << e.value();
   return out;
 }
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/QuadMatrix.cpp b/src/mathicgb/QuadMatrix.cpp
index d1a4944..58167f0 100755
--- a/src/mathicgb/QuadMatrix.cpp
+++ b/src/mathicgb/QuadMatrix.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "QuadMatrix.hpp"
 
@@ -6,6 +8,8 @@
 #include <ostream>
 #include <sstream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 bool QuadMatrix::debugAssertValid() const {
 #ifndef MATHICGB_DEBUG
   return true;
@@ -29,7 +33,7 @@ bool QuadMatrix::debugAssertValid() const {
 #endif
 }
 
-void QuadMatrix::print(std::ostream& out) const {
+void QuadMatrix::print(::std::ostream& out) const {
   MATHICGB_ASSERT(debugAssertValid());
 
   typedef SparseMatrix::ColIndex ColIndex;
@@ -74,22 +78,22 @@ SparseMatrix::ColIndex QuadMatrix::computeLeftColCount() const {
   if (!leftColumnMonomials.empty()) {
     MATHICGB_ASSERT(
       leftColumnMonomials.size() <=
-      std::numeric_limits<SparseMatrix::ColIndex>::max()
+      ::std::numeric_limits<SparseMatrix::ColIndex>::max()
     );
     return static_cast<SparseMatrix::ColIndex>(leftColumnMonomials.size());
   }
-  return std::max(topLeft.computeColCount(), bottomLeft.computeColCount());
+  return ::std::max(topLeft.computeColCount(), bottomLeft.computeColCount());
 }
 
 SparseMatrix::ColIndex QuadMatrix::computeRightColCount() const {
   if (!rightColumnMonomials.empty()) {
     MATHICGB_ASSERT(
       rightColumnMonomials.size() <=
-      std::numeric_limits<SparseMatrix::ColIndex>::max()
+      ::std::numeric_limits<SparseMatrix::ColIndex>::max()
     );
     return static_cast<SparseMatrix::ColIndex>(rightColumnMonomials.size());
   }
-  return std::max(topRight.computeColCount(), bottomRight.computeColCount());
+  return ::std::max(topRight.computeColCount(), bottomRight.computeColCount());
 }
 
 size_t QuadMatrix::entryCount() const {
@@ -98,8 +102,8 @@ size_t QuadMatrix::entryCount() const {
     bottomLeft.entryCount() + bottomRight.entryCount();
 }
 
-std::string QuadMatrix::toString() const {
-  std::ostringstream out;
+::std::string QuadMatrix::toString() const {
+  ::std::ostringstream out;
   print(out);
   return out.str();
 }
@@ -114,7 +118,7 @@ size_t QuadMatrix::memoryUseTrimmed() const {
 	bottomLeft.memoryUseTrimmed() + bottomRight.memoryUseTrimmed();
 }
 
-void QuadMatrix::printStatistics(std::ostream& out) const {
+void QuadMatrix::printStatistics(::std::ostream& out) const {
   typedef mathic::ColumnPrinter ColPr;
 
   ColPr pr;
@@ -127,7 +131,7 @@ void QuadMatrix::printStatistics(std::ostream& out) const {
   const auto totalMemory = memoryUse();
 
   auto printDataCol = [&](
-    std::ostream& out,
+    ::std::ostream& out,
     const SparseMatrix& top,
     const SparseMatrix& bottom,
     const SparseMatrix::ColIndex colCount
@@ -209,12 +213,12 @@ QuadMatrix QuadMatrix::toCanonical() const {
   // todo: eliminate left/right code duplication here
   QuadMatrix matrix;
   { // left side
-    std::vector<SparseMatrix::RowIndex> rows;
+    ::std::vector<SparseMatrix::RowIndex> rows;
     for (SparseMatrix::RowIndex row = 0; row < topLeft.rowCount(); ++row)
       rows.push_back(row);
     {
       RowComparer comparer(topLeft);
-      std::sort(rows.begin(), rows.end(), comparer);
+      ::std::sort(rows.begin(), rows.end(), comparer);
     }
 
     matrix.topLeft.clear();
@@ -225,12 +229,12 @@ QuadMatrix QuadMatrix::toCanonical() const {
     }
   }
   { // right side
-    std::vector<SparseMatrix::RowIndex> rows;
+    ::std::vector<SparseMatrix::RowIndex> rows;
     for (SparseMatrix::RowIndex row = 0; row < bottomLeft.rowCount(); ++row)
       rows.push_back(row);
     {
       RowComparer comparer(bottomLeft);
-      std::sort(rows.begin(), rows.end(), comparer);
+      ::std::sort(rows.begin(), rows.end(), comparer);
     }
 
     matrix.bottomLeft.clear();
@@ -245,10 +249,10 @@ QuadMatrix QuadMatrix::toCanonical() const {
   matrix.rightColumnMonomials = rightColumnMonomials;
   matrix.ring = ring;
   
-  return std::move(matrix);
+  return ::std::move(matrix);
 }
 
-std::ostream& operator<<(std::ostream& out, const QuadMatrix& qm) {
+::std::ostream& operator<<(::std::ostream& out, const QuadMatrix& qm) {
   qm.print(out);
   return out;
 }
@@ -259,7 +263,7 @@ namespace {
     ColumnComparer(const PolyRing& ring): mRing(ring) {}
 
     typedef SparseMatrix::ColIndex ColIndex;
-    typedef std::pair<monomial, ColIndex> Pair;
+    typedef ::std::pair<monomial, ColIndex> Pair;
     bool operator()(const Pair& a, const Pair b) const {
       return mRing.monomialLT(b.first, a.first);
     }
@@ -268,20 +272,20 @@ namespace {
     const PolyRing& mRing;
   };
 
-  std::vector<SparseMatrix::ColIndex> sortColumnMonomialsAndMakePermutation(
-    std::vector<monomial>& monomials,
+  ::std::vector<SparseMatrix::ColIndex> sortColumnMonomialsAndMakePermutation(
+    ::std::vector<monomial>& monomials,
     const PolyRing& ring
   ) {
     typedef SparseMatrix::ColIndex ColIndex;
-    MATHICGB_ASSERT(monomials.size() <= std::numeric_limits<ColIndex>::max());
+    MATHICGB_ASSERT(monomials.size() <= ::std::numeric_limits<ColIndex>::max());
     const ColIndex colCount = static_cast<ColIndex>(monomials.size());
     // Monomial needs to be non-const as we are going to put these
     // monomials back into the vector of monomials which is not const.
-    std::vector<std::pair<monomial, ColIndex>> columns;
+    ::std::vector< ::std::pair<monomial, ColIndex>> columns;
     columns.reserve(colCount);
     for (ColIndex col = 0; col < colCount; ++col)
-      columns.push_back(std::make_pair(monomials[col], col));
-    std::sort(columns.begin(), columns.end(), ColumnComparer(ring));
+      columns.push_back(::std::make_pair(monomials[col], col));
+    ::std::sort(columns.begin(), columns.end(), ColumnComparer(ring));
 
     // Apply sorting permutation to monomials. This is why it is necessary to
     // copy the values in monomial out of there: in-place application of a
@@ -295,21 +299,21 @@ namespace {
     }
 
     // Construct permutation of indices to match permutation of monomials
-    std::vector<ColIndex> permutation(colCount);
+    ::std::vector<ColIndex> permutation(colCount);
     for (ColIndex col = 0; col < colCount; ++col) {
       // The monomial for column columns[col].second is now the
       // monomial for col, so we need the inverse map for indices.
       permutation[columns[col].second] = col;
     }
 
-    return std::move(permutation);
+    return ::std::move(permutation);
   }
 }
 
 void QuadMatrix::sortColumnsLeftRightParallel() {
   typedef SparseMatrix::ColIndex ColIndex;
-  std::vector<ColIndex> leftPermutation;
-  std::vector<ColIndex> rightPermutation;
+  ::std::vector<ColIndex> leftPermutation;
+  ::std::vector<ColIndex> rightPermutation;
   
   mgb::tbb::parallel_for(0, 2, 1, [&](int i) {
     if (i == 0)
@@ -366,3 +370,5 @@ SparseMatrix::Scalar QuadMatrix::read(FILE* file) {
 
   return topLeftModulus;
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/QuadMatrix.hpp b/src/mathicgb/QuadMatrix.hpp
index 35594df..81b9b0d 100755
--- a/src/mathicgb/QuadMatrix.hpp
+++ b/src/mathicgb/QuadMatrix.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_QUAD_MATRIX_GUARD
 #define MATHICGB_QUAD_MATRIX_GUARD
 
@@ -6,6 +8,9 @@
 #include <vector>
 #include <string>
 #include <ostream>
+
+MATHICGB_NAMESPACE_BEGIN
+
 class ostream;
 
 /** Represents a matrix composed of 4 sub-matrices that fit together
@@ -20,18 +25,18 @@ public:
   QuadMatrix() {}
 
   QuadMatrix(QuadMatrix&& matrix):
-    topLeft(std::move(matrix.topLeft)),
-    topRight(std::move(matrix.topRight)),
-    bottomLeft(std::move(matrix.bottomLeft)),
-    bottomRight(std::move(matrix.bottomRight)),
-    leftColumnMonomials(std::move(matrix.leftColumnMonomials)),
-    rightColumnMonomials(std::move(matrix.rightColumnMonomials)),
+    topLeft(::std::move(matrix.topLeft)),
+    topRight(::std::move(matrix.topRight)),
+    bottomLeft(::std::move(matrix.bottomLeft)),
+    bottomRight(::std::move(matrix.bottomRight)),
+    leftColumnMonomials(::std::move(matrix.leftColumnMonomials)),
+    rightColumnMonomials(::std::move(matrix.rightColumnMonomials)),
     ring(matrix.ring)
   {}
 
   QuadMatrix& operator=(QuadMatrix&& matrix) {
     this->~QuadMatrix();
-    new (this) QuadMatrix(std::move(matrix));
+    new (this) QuadMatrix(::std::move(matrix));
     return *this;
   }
 
@@ -39,21 +44,21 @@ public:
   SparseMatrix topRight;
   SparseMatrix bottomLeft;
   SparseMatrix bottomRight;
-  std::vector<monomial> leftColumnMonomials;
-  std::vector<monomial> rightColumnMonomials;
+  ::std::vector<monomial> leftColumnMonomials;
+  ::std::vector<monomial> rightColumnMonomials;
   const PolyRing* ring;
 
   /// Prints whole matrix to out in human-readable format. Useful for
   /// debugging.
-  void print(std::ostream& out) const;
+  void print(::std::ostream& out) const;
 
-  void printStatistics(std::ostream& out) const;
+  void printStatistics(::std::ostream& out) const;
 
   size_t memoryUse() const;
   size_t memoryUseTrimmed() const;
 
   /// Shows whole matrix in a string. Useful for debugging.
-  std::string toString() const;
+  ::std::string toString() const;
 
   /// Return the combined number of non-zero entries.
   size_t entryCount() const;
@@ -89,6 +94,8 @@ private:
   void operator=(const QuadMatrix&); // not available
 };
 
-std::ostream& operator<<(std::ostream& out, const QuadMatrix& qm);
+::std::ostream& operator<<(::std::ostream& out, const QuadMatrix& qm);
+
+MATHICGB_NAMESPACE_END
 
 #endif
diff --git a/src/mathicgb/QuadMatrixBuilder.cpp b/src/mathicgb/QuadMatrixBuilder.cpp
index 29a8a99..b963836 100755
--- a/src/mathicgb/QuadMatrixBuilder.cpp
+++ b/src/mathicgb/QuadMatrixBuilder.cpp
@@ -1,127 +1,133 @@
-#include "stdinc.h"
-#include "QuadMatrixBuilder.hpp"
-
-#include "QuadMatrix.hpp"
-#include <mathic.h>
-#include <sstream>
-
-QuadMatrixBuilder::QuadMatrixBuilder(
-  const PolyRing& ring,
-  Map& map,
-  MonomialsType& monomialsLeft,
-  MonomialsType& monomialsRight,
-  const size_t memoryQuantum
-):
-  mMonomialToCol(map),
-  mTopLeft(memoryQuantum),
-  mTopRight(memoryQuantum),
-  mBottomLeft(memoryQuantum),
-  mBottomRight(memoryQuantum),
-  mMonomialsLeft(monomialsLeft),
-  mMonomialsRight(monomialsRight)
-{}
-
-void QuadMatrixBuilder::takeRowsFrom(QuadMatrix&& matrix) {
-  MATHICGB_ASSERT(&ring() == matrix.ring);
-  MATHICGB_ASSERT(matrix.debugAssertValid());
-
-  mTopLeft.takeRowsFrom(std::move(matrix.topLeft));
-  mTopRight.takeRowsFrom(std::move(matrix.topRight));
-  mBottomLeft.takeRowsFrom(std::move(matrix.bottomLeft));
-  mBottomRight.takeRowsFrom(std::move(matrix.bottomRight));
-}
-
-
-namespace {
-  /// Creates a column and updates the associated data structures that
-  /// are passed in. Copies mono - ownership is not taken over. The
-  /// purpose of this function is to avoid code duplication. It is a            
-  /// template in order to avoid referring to private types of
-  /// QuadMatrixBuilder.
-  template<class ToMono, class ToCol>
-  std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
-  createCol(
-    const_monomial mono,
-    SparseMatrix& top,
-    SparseMatrix& bottom,
-    ToMono& toMonomial,
-    ToCol& toCol,
-    const PolyRing& ring,
-    const bool left
-  ) {
-    MATHICGB_ASSERT(typename ToCol::Reader(toCol).find(mono).first == 0);
-
-    const auto colCount =
-      static_cast<QuadMatrixBuilder::ColIndex>(toMonomial.size());
-    if (colCount == std::numeric_limits<QuadMatrixBuilder::ColIndex>::max())
-      throw std::overflow_error("Too many columns in QuadMatrixBuilder");
-
-    toMonomial.push_back(0); // allocate memory now to avoid bad_alloc later
-    monomial copied = ring.allocMonomial();
-    ring.monomialCopy(mono, copied);
-    std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial> p;
-    try {
-      auto inserted = toCol.insert(std::make_pair(
-          copied, QuadMatrixBuilder::LeftRightColIndex(colCount, left))
-      );
-      MATHICGB_ASSERT(inserted.second);
-      MATHICGB_ASSERT(inserted.first.first != 0);
-      auto p(inserted.first);
-      toMonomial.back() = copied;
-
-      MATHICGB_ASSERT(ring.monomialEqualHintTrue(copied, p.second));
-      MATHICGB_ASSERT(*p.first == QuadMatrixBuilder::LeftRightColIndex(colCount, left));
-      return std::make_pair(*p.first, p.second);
-    } catch (...) {
-      toMonomial.pop_back();
-      ring.freeMonomial(copied);
-      throw;
-    }
-  }
-}
-
-std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
-QuadMatrixBuilder::createColumnLeft(
-  const_monomial monomialToBeCopied
-) {
-  return createCol
-    (monomialToBeCopied,
-     mTopLeft,
-     mBottomLeft,
-     mMonomialsLeft,
-     mMonomialToCol,
-     ring(),
-     true);
-}
-
-std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
-QuadMatrixBuilder::createColumnRight(
-  const_monomial monomialToBeCopied
-) {
-  return createCol
-    (monomialToBeCopied,
-     mTopRight,
-     mBottomRight,
-     mMonomialsRight,
-     mMonomialToCol,
-     ring(),
-     false);
-}
-
-QuadMatrix QuadMatrixBuilder::buildMatrixAndClear() {
-  QuadMatrix out;
-
-  mTopLeft.swap(out.topLeft);
-  mTopRight.swap(out.topRight);
-  mBottomLeft.swap(out.bottomLeft);
-  mBottomRight.swap(out.bottomRight);
-  out.ring = &ring();
-
-  mTopLeft.clear();
-  mTopRight.clear();
-  mBottomLeft.clear();
-  mBottomRight.clear();
-
-  MATHICGB_ASSERT(out.debugAssertValid());
-  return std::move(out);
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "stdinc.h"
+#include "QuadMatrixBuilder.hpp"
+
+#include "QuadMatrix.hpp"
+#include <mathic.h>
+#include <sstream>
+
+MATHICGB_NAMESPACE_BEGIN
+
+QuadMatrixBuilder::QuadMatrixBuilder(
+  const PolyRing& ring,
+  Map& map,
+  MonomialsType& monomialsLeft,
+  MonomialsType& monomialsRight,
+  const size_t memoryQuantum
+):
+  mMonomialToCol(map),
+  mTopLeft(memoryQuantum),
+  mTopRight(memoryQuantum),
+  mBottomLeft(memoryQuantum),
+  mBottomRight(memoryQuantum),
+  mMonomialsLeft(monomialsLeft),
+  mMonomialsRight(monomialsRight)
+{}
+
+void QuadMatrixBuilder::takeRowsFrom(QuadMatrix&& matrix) {
+  MATHICGB_ASSERT(&ring() == matrix.ring);
+  MATHICGB_ASSERT(matrix.debugAssertValid());
+
+  mTopLeft.takeRowsFrom(::std::move(matrix.topLeft));
+  mTopRight.takeRowsFrom(::std::move(matrix.topRight));
+  mBottomLeft.takeRowsFrom(::std::move(matrix.bottomLeft));
+  mBottomRight.takeRowsFrom(::std::move(matrix.bottomRight));
+}
+
+
+namespace {
+  /// Creates a column and updates the associated data structures that
+  /// are passed in. Copies mono - ownership is not taken over. The
+  /// purpose of this function is to avoid code duplication. It is a            
+  /// template in order to avoid referring to private types of
+  /// QuadMatrixBuilder.
+  template<class ToMono, class ToCol>
+  ::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+  createCol(
+    const_monomial mono,
+    SparseMatrix& top,
+    SparseMatrix& bottom,
+    ToMono& toMonomial,
+    ToCol& toCol,
+    const PolyRing& ring,
+    const bool left
+  ) {
+    MATHICGB_ASSERT(typename ToCol::Reader(toCol).find(mono).first == 0);
+
+    const auto colCount =
+      static_cast<QuadMatrixBuilder::ColIndex>(toMonomial.size());
+    if (colCount == ::std::numeric_limits<QuadMatrixBuilder::ColIndex>::max())
+      throw ::std::overflow_error("Too many columns in QuadMatrixBuilder");
+
+    toMonomial.push_back(0); // allocate memory now to avoid bad_alloc later
+    monomial copied = ring.allocMonomial();
+    ring.monomialCopy(mono, copied);
+    ::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial> p;
+    try {
+      auto inserted = toCol.insert(::std::make_pair(
+          copied, QuadMatrixBuilder::LeftRightColIndex(colCount, left))
+      );
+      MATHICGB_ASSERT(inserted.second);
+      MATHICGB_ASSERT(inserted.first.first != 0);
+      auto p(inserted.first);
+      toMonomial.back() = copied;
+
+      MATHICGB_ASSERT(ring.monomialEqualHintTrue(copied, p.second));
+      MATHICGB_ASSERT(*p.first == QuadMatrixBuilder::LeftRightColIndex(colCount, left));
+      return ::std::make_pair(*p.first, p.second);
+    } catch (...) {
+      toMonomial.pop_back();
+      ring.freeMonomial(copied);
+      throw;
+    }
+  }
+}
+
+::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+QuadMatrixBuilder::createColumnLeft(
+  const_monomial monomialToBeCopied
+) {
+  return createCol
+    (monomialToBeCopied,
+     mTopLeft,
+     mBottomLeft,
+     mMonomialsLeft,
+     mMonomialToCol,
+     ring(),
+     true);
+}
+
+::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+QuadMatrixBuilder::createColumnRight(
+  const_monomial monomialToBeCopied
+) {
+  return createCol
+    (monomialToBeCopied,
+     mTopRight,
+     mBottomRight,
+     mMonomialsRight,
+     mMonomialToCol,
+     ring(),
+     false);
+}
+
+QuadMatrix QuadMatrixBuilder::buildMatrixAndClear() {
+  QuadMatrix out;
+
+  mTopLeft.swap(out.topLeft);
+  mTopRight.swap(out.topRight);
+  mBottomLeft.swap(out.bottomLeft);
+  mBottomRight.swap(out.bottomRight);
+  out.ring = &ring();
+
+  mTopLeft.clear();
+  mTopRight.clear();
+  mBottomLeft.clear();
+  mBottomRight.clear();
+
+  MATHICGB_ASSERT(out.debugAssertValid());
+  return ::std::move(out);
+}
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/QuadMatrixBuilder.hpp b/src/mathicgb/QuadMatrixBuilder.hpp
index 53763df..8b2b556 100755
--- a/src/mathicgb/QuadMatrixBuilder.hpp
+++ b/src/mathicgb/QuadMatrixBuilder.hpp
@@ -1,199 +1,204 @@
-#ifndef MATHICGB_QUAD_MATRIX_BUILDER_GUARD
-#define MATHICGB_QUAD_MATRIX_BUILDER_GUARD
-
-#include "MonomialMap.hpp"
-
-#include "SparseMatrix.hpp"
-#include "PolyRing.hpp"
-#include <vector>
-#include <map>
-#include <limits>
-#include <string>
-#include <ostream>
-#include <memtailor.h>
-class QuadMatrix;
-
-/** Builder for QuadMatrix. This is not quite the builder pattern in
-  that the interface is not virtual and the implementation cannot be
-  swapped out - it only follows the builder pattern in that it is a
-  class that allows step-wise construction of a final product. */
-class QuadMatrixBuilder {
- public:
-  typedef SparseMatrix::RowIndex RowIndex;
-  typedef SparseMatrix::ColIndex ColIndex;
-  typedef SparseMatrix::Scalar Scalar;
-
-  /// The index of a column that can be either on the left or the
-  /// right side. The largest representable ColIndex is an invalid
-  /// index. This is the default value. The only allowed method to
-  /// call for an invalid index is valid().
-  class LeftRightColIndex {
-  public:
-    LeftRightColIndex():
-      mRawIndex(std::numeric_limits<ColIndex>::max()), mLeft(false) {}
-    LeftRightColIndex(ColIndex index, bool left):
-      mRawIndex(index), mLeft(left) {
-    }
-
-    ColIndex leftIndex() const {
-      MATHICGB_ASSERT(left());
-      return index();
-    }
-
-    ColIndex rightIndex() const {
-      MATHICGB_ASSERT(right());
-      return index();
-    }
-
-    /// Use leftIndex() or rightIndex() instead if you know what side
-    /// you are expecting, as this does an assert on your expectation.
-    ColIndex index() const {
-      MATHICGB_ASSERT(valid());
-      return mRawIndex;
-    }
-
-    bool left() const {
-      MATHICGB_ASSERT(valid());
-      return mLeft;
-    }
-
-    bool right() const {
-      MATHICGB_ASSERT(valid());
-      return !left();
-    }
-
-    bool valid() const {
-      return mRawIndex != std::numeric_limits<ColIndex>::max();
-    }
-
-    bool operator==(const LeftRightColIndex& index) const {
-      return mRawIndex == index.mRawIndex && mLeft == index.mLeft;
-    }
-
-    bool operator!=(const LeftRightColIndex& index) const {
-      return !(*this == index);
-    }
-
-  private:
-    ColIndex mRawIndex;
-    bool mLeft;
-  };
-
-  typedef MonomialMap<LeftRightColIndex> Map;
-  typedef std::vector<monomial> MonomialsType;
-
-  QuadMatrixBuilder(
-    const PolyRing& ring,
-    Map& map,
-    MonomialsType& monomialsLeft,
-    MonomialsType& monomialsRight,
-    size_t memoryQuantum = 0
-  );
-
-  /// Inserts the rows from builder. To avoid an assert either the matrix must
-  /// have no column monomials specified or the monomials that are specified
-  /// must match exactly to the column monomials for this object --- including
-  /// the ordering of the monomials.
-  void takeRowsFrom(QuadMatrix&& matrix);
-
-  size_t memoryQuantum() const {
-    return mTopLeft.memoryQuantum();
-  }
-
-  // **** Appending entries to top matrices.
-  // Same interface as SparseMatrix except with two matrices and here
-  // you have to create columns before you can use them.
-
-  void appendEntryTopLeft(ColIndex col, Scalar scalar) {
-    mTopLeft.appendEntry(col, scalar);
-  }
-
-  void appendEntryTopRight(ColIndex col, Scalar scalar) {
-    mTopRight.appendEntry(col, scalar);
-  }
-
-  void appendEntryTop(LeftRightColIndex col, Scalar scalar) {
-    MATHICGB_ASSERT(col.valid());
-    if (col.left())
-      appendEntryTopLeft(col.leftIndex(), scalar);
-    else
-      appendEntryTopRight(col.rightIndex(), scalar);
-  }
-
-  void rowDoneTopLeftAndRight() {
-    mTopLeft.rowDone();
-    mTopRight.rowDone();
-  }
-
-  // **** Appending entries to bottom matrices
-  // Same interface as SparseMatrix except with two matrices and here
-  // you have to create columns before you can use them.
-
-  void appendEntryBottomLeft(ColIndex col, Scalar scalar) {
-    mBottomLeft.appendEntry(col, scalar);
-  }
-
-  void appendEntryBottomRight(ColIndex col, Scalar scalar) {
-    mBottomRight.appendEntry(col, scalar);
-  }
-
-  void appendEntryBottom(LeftRightColIndex col, Scalar scalar) {
-    MATHICGB_ASSERT(col.valid());
-    if (col.left())
-      appendEntryBottomLeft(col.leftIndex(), scalar);
-    else
-      appendEntryBottomRight(col.rightIndex(), scalar);
-  }
-
-  void rowDoneBottomLeftAndRight() {
-    mBottomLeft.rowDone();
-    mBottomRight.rowDone();
-  }
-
-  // *** Creating and reordering columns
-  // You have to create columns before you can append entries in those columns.
-  // All passed in monomials are copied so that ownership of the memory is
-  // not taken over. The creation methods return a LeftRightColIndex instead
-  // of just a ColIndex to allow more of a chance for asserts to catch errors
-  // and to avoid the need for the client to immediately construct a
-  // LeftRightColIndex based on the return value.
-
-  /** Creates a new column associated to the monomial
-    monomialToBeCopied to the left matrices. There must not already
-    exist a column for this monomial on the left or on the right. */
-  std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
-  createColumnLeft(const_monomial monomialToBeCopied);
-
-  /** Creates a new column associated to the monomial monomialToBeCopied
-    to the right matrices. There must not already exist a column for
-    this monomial on the left or on the right. */
-  std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
-  createColumnRight(const_monomial monomialToBeCopied);
-
-  // *** Querying columns
-
-  const SparseMatrix& topLeft() const {return mTopLeft;}
-  const SparseMatrix& topRight() const {return mTopRight;}
-  const SparseMatrix& bottomLeft() const {return mBottomLeft;}
-  const SparseMatrix& bottomRight() const {return mBottomRight;}
-
-  const PolyRing& ring() const {return mMonomialToCol.ring();}
-
-  /// Returns the built matrix and sets the builder to a state
-  /// with no columns and no rows.
-  QuadMatrix buildMatrixAndClear();
-
-private:
-  MonomialsType& mMonomialsLeft; /// stores one monomial per left column
-  MonomialsType& mMonomialsRight; /// stores one monomial per right column
-
-  /// Used for fast determination of which column has a given monomial.
-  Map& mMonomialToCol;
-
-  SparseMatrix mTopLeft;
-  SparseMatrix mTopRight;
-  SparseMatrix mBottomLeft;
-  SparseMatrix mBottomRight;
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_QUAD_MATRIX_BUILDER_GUARD
+#define MATHICGB_QUAD_MATRIX_BUILDER_GUARD
+
+#include "MonomialMap.hpp"
+#include "SparseMatrix.hpp"
+#include "PolyRing.hpp"
+#include <vector>
+#include <map>
+#include <limits>
+#include <string>
+#include <ostream>
+#include <memtailor.h>
+
+MATHICGB_NAMESPACE_BEGIN
+
+class QuadMatrix;
+
+/** Builder for QuadMatrix. This is not quite the builder pattern in
+  that the interface is not virtual and the implementation cannot be
+  swapped out - it only follows the builder pattern in that it is a
+  class that allows step-wise construction of a final product. */
+class QuadMatrixBuilder {
+ public:
+  typedef SparseMatrix::RowIndex RowIndex;
+  typedef SparseMatrix::ColIndex ColIndex;
+  typedef SparseMatrix::Scalar Scalar;
+
+  /// The index of a column that can be either on the left or the
+  /// right side. The largest representable ColIndex is an invalid
+  /// index. This is the default value. The only allowed method to
+  /// call for an invalid index is valid().
+  class LeftRightColIndex {
+  public:
+    LeftRightColIndex():
+      mRawIndex(::std::numeric_limits<ColIndex>::max()), mLeft(false) {}
+    LeftRightColIndex(ColIndex index, bool left):
+      mRawIndex(index), mLeft(left) {
+    }
+
+    ColIndex leftIndex() const {
+      MATHICGB_ASSERT(left());
+      return index();
+    }
+
+    ColIndex rightIndex() const {
+      MATHICGB_ASSERT(right());
+      return index();
+    }
+
+    /// Use leftIndex() or rightIndex() instead if you know what side
+    /// you are expecting, as this does an assert on your expectation.
+    ColIndex index() const {
+      MATHICGB_ASSERT(valid());
+      return mRawIndex;
+    }
+
+    bool left() const {
+      MATHICGB_ASSERT(valid());
+      return mLeft;
+    }
+
+    bool right() const {
+      MATHICGB_ASSERT(valid());
+      return !left();
+    }
+
+    bool valid() const {
+      return mRawIndex != ::std::numeric_limits<ColIndex>::max();
+    }
+
+    bool operator==(const LeftRightColIndex& index) const {
+      return mRawIndex == index.mRawIndex && mLeft == index.mLeft;
+    }
+
+    bool operator!=(const LeftRightColIndex& index) const {
+      return !(*this == index);
+    }
+
+  private:
+    ColIndex mRawIndex;
+    bool mLeft;
+  };
+
+  typedef MonomialMap<LeftRightColIndex> Map;
+  typedef ::std::vector<monomial> MonomialsType;
+
+  QuadMatrixBuilder(
+    const PolyRing& ring,
+    Map& map,
+    MonomialsType& monomialsLeft,
+    MonomialsType& monomialsRight,
+    size_t memoryQuantum = 0
+  );
+
+  /// Inserts the rows from builder. To avoid an assert either the matrix must
+  /// have no column monomials specified or the monomials that are specified
+  /// must match exactly to the column monomials for this object --- including
+  /// the ordering of the monomials.
+  void takeRowsFrom(QuadMatrix&& matrix);
+
+  size_t memoryQuantum() const {
+    return mTopLeft.memoryQuantum();
+  }
+
+  // **** Appending entries to top matrices.
+  // Same interface as SparseMatrix except with two matrices and here
+  // you have to create columns before you can use them.
+
+  void appendEntryTopLeft(ColIndex col, Scalar scalar) {
+    mTopLeft.appendEntry(col, scalar);
+  }
+
+  void appendEntryTopRight(ColIndex col, Scalar scalar) {
+    mTopRight.appendEntry(col, scalar);
+  }
+
+  void appendEntryTop(LeftRightColIndex col, Scalar scalar) {
+    MATHICGB_ASSERT(col.valid());
+    if (col.left())
+      appendEntryTopLeft(col.leftIndex(), scalar);
+    else
+      appendEntryTopRight(col.rightIndex(), scalar);
+  }
+
+  void rowDoneTopLeftAndRight() {
+    mTopLeft.rowDone();
+    mTopRight.rowDone();
+  }
+
+  // **** Appending entries to bottom matrices
+  // Same interface as SparseMatrix except with two matrices and here
+  // you have to create columns before you can use them.
+
+  void appendEntryBottomLeft(ColIndex col, Scalar scalar) {
+    mBottomLeft.appendEntry(col, scalar);
+  }
+
+  void appendEntryBottomRight(ColIndex col, Scalar scalar) {
+    mBottomRight.appendEntry(col, scalar);
+  }
+
+  void appendEntryBottom(LeftRightColIndex col, Scalar scalar) {
+    MATHICGB_ASSERT(col.valid());
+    if (col.left())
+      appendEntryBottomLeft(col.leftIndex(), scalar);
+    else
+      appendEntryBottomRight(col.rightIndex(), scalar);
+  }
+
+  void rowDoneBottomLeftAndRight() {
+    mBottomLeft.rowDone();
+    mBottomRight.rowDone();
+  }
+
+  // *** Creating and reordering columns
+  // You have to create columns before you can append entries in those columns.
+  // All passed in monomials are copied so that ownership of the memory is
+  // not taken over. The creation methods return a LeftRightColIndex instead
+  // of just a ColIndex to allow more of a chance for asserts to catch errors
+  // and to avoid the need for the client to immediately construct a
+  // LeftRightColIndex based on the return value.
+
+  /** Creates a new column associated to the monomial
+    monomialToBeCopied to the left matrices. There must not already
+    exist a column for this monomial on the left or on the right. */
+  ::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+  createColumnLeft(const_monomial monomialToBeCopied);
+
+  /** Creates a new column associated to the monomial monomialToBeCopied
+    to the right matrices. There must not already exist a column for
+    this monomial on the left or on the right. */
+  ::std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
+  createColumnRight(const_monomial monomialToBeCopied);
+
+  // *** Querying columns
+
+  const SparseMatrix& topLeft() const {return mTopLeft;}
+  const SparseMatrix& topRight() const {return mTopRight;}
+  const SparseMatrix& bottomLeft() const {return mBottomLeft;}
+  const SparseMatrix& bottomRight() const {return mBottomRight;}
+
+  const PolyRing& ring() const {return mMonomialToCol.ring();}
+
+  /// Returns the built matrix and sets the builder to a state
+  /// with no columns and no rows.
+  QuadMatrix buildMatrixAndClear();
+
+private:
+  MonomialsType& mMonomialsLeft; /// stores one monomial per left column
+  MonomialsType& mMonomialsRight; /// stores one monomial per right column
+
+  /// Used for fast determination of which column has a given monomial.
+  Map& mMonomialToCol;
+
+  SparseMatrix mTopLeft;
+  SparseMatrix mTopRight;
+  SparseMatrix mBottomLeft;
+  SparseMatrix mBottomRight;
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/RawVector.hpp b/src/mathicgb/RawVector.hpp
index 9c7d6e4..88a3447 100755
--- a/src/mathicgb/RawVector.hpp
+++ b/src/mathicgb/RawVector.hpp
@@ -1,307 +1,312 @@
-#ifndef MATHICGB_RAW_VECTOR_GUARD
-#define MATHICGB_RAW_VECTOR_GUARD
-
-#include <iterator>
-#include <cstddef>
-#include <memory>
-#include <utility>
-#include <algorithm>
-#include <stdexcept>
-#include <cstring>
-
-/// RawVector mimics std::vector except that it does not do memory management.
-/// So you can directly access the pointers to memory and you can replace them
-/// with any other pointers that you need to.
-///
-/// Warning: RawVector is called raw because it does not allocate any memory,
-/// so it is an error to insert elements that there is not enough space for -
-/// you need to make sure ahead of time that there is enough space.
-///
-/// This class makes it possible to have a lot of the convenience of the
-/// std::vector interface even in places where std::vector cannot be used
-/// because of a need for manual memory management.
-template<class T>
-class RawVector {
-public:
-  typedef T& reference;
-  typedef const T& const_reference;
-  typedef T* iterator;
-  typedef const T* const_iterator;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef T value_type;
-  typedef T* pointer;
-  typedef const T* const_pointer;
-  typedef std::reverse_iterator<iterator> reverse_iterator;
-  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-  /// Initializes to the null state.
-  RawVector(): mBegin(0), mEnd(0), mCapacityEnd(0) {}
-
-  /// Copies the pointers from v. It is a shallow copy.
-  RawVector(const RawVector& v):
-    mBegin(v.mBegin),
-    mEnd(v.mEnd),
-    mCapacityEnd(v.mCapacityEnd) {}
-
-  /// Copies the pointers from v. It is a shallow copy. Sets v to a null state.
-  RawVector(RawVector&& v):
-    mBegin(v.mBegin),
-    mEnd(v.mEnd),
-    mCapacityEnd(v.mCapacityEnd)
-  {
-    v.releaseMemory();
-  }
-
-  RawVector(pointer begin, pointer end):
-    mBegin(begin),
-    mEnd(end),
-    mCapacityEnd(end) {}
-
-  RawVector(pointer begin, pointer end, pointer capacityEnd):
-    mBegin(begin),
-    mEnd(end),
-    mCapacityEnd(capacityEnd) {}
-
-  /// As clear() --- does not free memory.
-  ~RawVector() {
-    clear();
-  }
-
-  /// There is no operator== to avoid confusion about whether it compares
-  /// pointers or contents. Instead, there is this.
-  bool contentsEqual(const RawVector<T>& v) const {
-    return std::equal(begin(), end(), v.begin());
-  }
-
-  /// Copies the pointers from v. It is a shallow copy.
-  RawVector<T>& operator=(const RawVector& v) {
-    mBegin = v.mBegin;
-    mEnd = v.mEnd;
-    mCapacityEnd = v.mCapacityEnd;
-    return *this;
-  }
-
-  /// Copies the pointers from v. It is a shallow copy. Sets v to the null state.
-  RawVector<T>& operator=(RawVector&& v) {
-    mBegin = v.mBegin;
-    mEnd = v.mEnd;
-    mCapacityEnd = v.mCapacityEnd;
-    v.releaseMemory();
-    return *this;
-  }
-
-  iterator begin() {return mBegin;}
-  const_iterator begin() const {return mBegin;}
-  iterator end() {return mEnd;}
-  const_iterator end() const {return mEnd;}
-
-  reverse_iterator rbegin() {return reverse_iterator(end());}
-  const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
-  reverse_iterator rend() {return reverse_iterator(begin());}
-  const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
-
-  size_type size() const {return mEnd - mBegin;}
-  size_type max_size() const {return std::numeric_limits<size_type>::max();}
-
-  /// There must be enough capacity for the new size.
-  void resize(const size_type newSize) {
-    MATHICGB_ASSERT(newSize <= capacity());
-    while (newSize > size()) {
-      new (mEnd) T();
-      ++mEnd;
-    }
-    while (newSize < size()) {
-      --mEnd;
-      mEnd->~T();
-    }
-    MATHICGB_ASSERT(newSize == size());
-  }
-
-  size_type capacity() const {return mCapacityEnd - mBegin;}
-
-  bool empty() const {return mBegin == mEnd;}
-
-  reference operator[](size_type index) {
-    MATHICGB_ASSERT(index < size());
-    return mBegin[index];
-  }
-
-  const_reference operator[](size_type index) const {
-    MATHICGB_ASSERT(index < size());
-    return mBegin[index];
-  }
-
-  reference at(size_type index) {
-    if (index >= size())
-      throw std::out_of_range("Invalid index in RawVector::at.");
-    return mBegin[index];
-  }
-
-  const_reference at(size_type index) const {
-    if (index >= size())
-      throw std::out_of_range("Invalid index in RawVector::at.");
-    return mBegin[index];
-  }
-
-  reference front() {
-    MATHICGB_ASSERT(!empty());
-    return *mBegin;
-  }
-
-  const_reference front() const {
-    MATHICGB_ASSERT(!empty());
-    return *mBegin;
-  }
-
-  reference back() {
-    MATHICGB_ASSERT(!empty());
-    return *(mEnd - 1);
-  }
-
-  const_reference back() const {
-    MATHICGB_ASSERT(!empty());
-    return *(mEnd - 1);
-  }
-
-  size_t memoryUse() const {
-    return capacity() * sizeof(value_type);
-  }
-
-  size_t memoryUseTrimmed() const {
-    return size() * sizeof(value_type);
-  }
-
-  /// There must be enough capacity for the new size.
-  template<class Iter>
-  void rawAssign(Iter begin, Iter end) {
-    const size_t count = std::distance(begin, end);
-    MATHICGB_ASSERT(count <= capacity());
-    if (count > size())
-      resize(count);
-    std::copy(begin, end, mBegin);
-  }
-
-  /// There must be enough capacity for the new size.
-  void rawAssign(size_type count, const T& t) {
-    MATHICGB_ASSERT(count <= capacity());
-    if (count > size())
-      resize(count);
-    std::fill_n(begin(), count, t);
-  }
-
-  /// There must be enough capacity for the new size. This is why there is no
-  /// push_back and only a rawPushBack --- to remind you of the changed
-  /// contract.
-  void rawPushBack(const T& t) {
-    MATHICGB_ASSERT(size() < capacity());
-    new (mEnd) T(t);
-    ++mEnd;
-  }
-
-  void pop_back() {
-    MATHICGB_ASSERT(!empty());
-    mEnd->~T();
-    --mEnd;
-  }
-
-  void swap(RawVector<T>& v) {
-    std::swap(mBegin, v.mBegin);
-    std::swap(mEnd, v.mEnd);
-    std::swap(mCapacityEnd, v.mCapacityEnd);
-  }
-
-  void clear() {
-    while (!empty())
-      pop_back();
-  }
-
-  // **** Extra functionality not available on std::vector
-
-  // memcpy onto the end of the vector.
-  void memcpy(const T* from, size_t countOfT) {
-    MATHICGB_ASSERT(countOfT <= capacityToGo());
-    std::memcpy(mEnd, from, countOfT * sizeof(T));
-    mEnd += countOfT;
-  }
-
-  /// Unused capacity.
-  size_t capacityToGo() const {
-    return mCapacityEnd - mEnd;
-  }
-
-  /// Returns true if there is no more capacity left. That is, if
-  /// capacity() == size().
-  bool atCapacity() const {
-    return mEnd == mCapacityEnd;
-  }
-
-  /// Sets this object to its null state without destructing memory. Returns
-  /// a pointer to the previous beginning of the buffer.
-  pointer releaseMemory() {
-    const auto oldBegin = mBegin;
-    mBegin = 0;
-    mEnd = 0;
-    mCapacityEnd = 0;
-    return oldBegin;
-  }
-
-  /// Takes over the new memory that is passed in, copies the old values to the
-  /// new memory and destructs the old values. Returns a pointer to the previous
-  /// beginning of the buffer.
-  pointer setMemoryAndCopy(
-    pointer begin,
-    pointer capacityEnd
-  ) {
-    MATHICGB_ASSERT(size() <=
-      static_cast<size_type>(std::distance(begin, capacityEnd)));
-    const auto oldBegin = mBegin;
-    const auto end = std::copy(mBegin, mEnd, begin);
-    *this = RawVector<T>(begin, end, capacityEnd);
-    return oldBegin;
-  }
-
-  /// Takes over the new memory that is passed in without destructing memory.
-  /// Returns a pointer to the previous beginning of the buffer.
-  pointer releaseAndSetMemory(
-    pointer begin,
-    pointer end,
-    pointer capacityEnd
-  ) {
-    const auto oldBegin = mBegin;
-    mBegin = begin;
-    mEnd = end;
-    mCapacityEnd = capacityEnd;
-    return oldBegin;
-  }
-
-  /// Destructs memory and then takes over the new memory that is passed in.
-  /// Does not deallocate the backing memory. Returns a pointer to the previous
-  /// beginning of the buffer.
-  pointer clearAndSetMemory(
-    pointer begin,
-    pointer end,
-    pointer capacityEnd
-  ) {
-    clear();
-    const auto oldBegin = mBegin;
-    mBegin = begin;
-    mEnd = end;
-    mCapacityEnd = capacityEnd;
-    return oldBegin;
-  }
-
-private:
-  T* mBegin;
-  T* mEnd;
-  T* mCapacityEnd;
-};
-
-namespace std {
-  template<class T>
-  void swap(RawVector<T>& a, RawVector<T>& b) {
-    a.swap(b);
-  }
-}
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_RAW_VECTOR_GUARD
+#define MATHICGB_RAW_VECTOR_GUARD
+
+#include <iterator>
+#include <cstddef>
+#include <memory>
+#include <utility>
+#include <algorithm>
+#include <stdexcept>
+#include <cstring>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// RawVector mimics std::vector except that it does not do memory management.
+/// So you can directly access the pointers to memory and you can replace them
+/// with any other pointers that you need to.
+///
+/// Warning: RawVector is called raw because it does not allocate any memory,
+/// so it is an error to insert elements that there is not enough space for -
+/// you need to make sure ahead of time that there is enough space.
+///
+/// This class makes it possible to have a lot of the convenience of the
+/// std::vector interface even in places where std::vector cannot be used
+/// because of a need for manual memory management.
+template<class T>
+class RawVector {
+public:
+  typedef T& reference;
+  typedef const T& const_reference;
+  typedef T* iterator;
+  typedef const T* const_iterator;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef T value_type;
+  typedef T* pointer;
+  typedef const T* const_pointer;
+  typedef std::reverse_iterator<iterator> reverse_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+  /// Initializes to the null state.
+  RawVector(): mBegin(0), mEnd(0), mCapacityEnd(0) {}
+
+  /// Copies the pointers from v. It is a shallow copy.
+  RawVector(const RawVector& v):
+    mBegin(v.mBegin),
+    mEnd(v.mEnd),
+    mCapacityEnd(v.mCapacityEnd) {}
+
+  /// Copies the pointers from v. It is a shallow copy. Sets v to a null state.
+  RawVector(RawVector&& v):
+    mBegin(v.mBegin),
+    mEnd(v.mEnd),
+    mCapacityEnd(v.mCapacityEnd)
+  {
+    v.releaseMemory();
+  }
+
+  RawVector(pointer begin, pointer end):
+    mBegin(begin),
+    mEnd(end),
+    mCapacityEnd(end) {}
+
+  RawVector(pointer begin, pointer end, pointer capacityEnd):
+    mBegin(begin),
+    mEnd(end),
+    mCapacityEnd(capacityEnd) {}
+
+  /// As clear() --- does not free memory.
+  ~RawVector() {
+    clear();
+  }
+
+  /// There is no operator== to avoid confusion about whether it compares
+  /// pointers or contents. Instead, there is this.
+  bool contentsEqual(const RawVector<T>& v) const {
+    return std::equal(begin(), end(), v.begin());
+  }
+
+  /// Copies the pointers from v. It is a shallow copy.
+  RawVector<T>& operator=(const RawVector& v) {
+    mBegin = v.mBegin;
+    mEnd = v.mEnd;
+    mCapacityEnd = v.mCapacityEnd;
+    return *this;
+  }
+
+  /// Copies the pointers from v. It is a shallow copy. Sets v to the null state.
+  RawVector<T>& operator=(RawVector&& v) {
+    mBegin = v.mBegin;
+    mEnd = v.mEnd;
+    mCapacityEnd = v.mCapacityEnd;
+    v.releaseMemory();
+    return *this;
+  }
+
+  iterator begin() {return mBegin;}
+  const_iterator begin() const {return mBegin;}
+  iterator end() {return mEnd;}
+  const_iterator end() const {return mEnd;}
+
+  reverse_iterator rbegin() {return reverse_iterator(end());}
+  const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
+  reverse_iterator rend() {return reverse_iterator(begin());}
+  const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
+
+  size_type size() const {return mEnd - mBegin;}
+  size_type max_size() const {return std::numeric_limits<size_type>::max();}
+
+  /// There must be enough capacity for the new size.
+  void resize(const size_type newSize) {
+    MATHICGB_ASSERT(newSize <= capacity());
+    while (newSize > size()) {
+      new (mEnd) T();
+      ++mEnd;
+    }
+    while (newSize < size()) {
+      --mEnd;
+      mEnd->~T();
+    }
+    MATHICGB_ASSERT(newSize == size());
+  }
+
+  size_type capacity() const {return mCapacityEnd - mBegin;}
+
+  bool empty() const {return mBegin == mEnd;}
+
+  reference operator[](size_type index) {
+    MATHICGB_ASSERT(index < size());
+    return mBegin[index];
+  }
+
+  const_reference operator[](size_type index) const {
+    MATHICGB_ASSERT(index < size());
+    return mBegin[index];
+  }
+
+  reference at(size_type index) {
+    if (index >= size())
+      throw std::out_of_range("Invalid index in RawVector::at.");
+    return mBegin[index];
+  }
+
+  const_reference at(size_type index) const {
+    if (index >= size())
+      throw std::out_of_range("Invalid index in RawVector::at.");
+    return mBegin[index];
+  }
+
+  reference front() {
+    MATHICGB_ASSERT(!empty());
+    return *mBegin;
+  }
+
+  const_reference front() const {
+    MATHICGB_ASSERT(!empty());
+    return *mBegin;
+  }
+
+  reference back() {
+    MATHICGB_ASSERT(!empty());
+    return *(mEnd - 1);
+  }
+
+  const_reference back() const {
+    MATHICGB_ASSERT(!empty());
+    return *(mEnd - 1);
+  }
+
+  size_t memoryUse() const {
+    return capacity() * sizeof(value_type);
+  }
+
+  size_t memoryUseTrimmed() const {
+    return size() * sizeof(value_type);
+  }
+
+  /// There must be enough capacity for the new size.
+  template<class Iter>
+  void rawAssign(Iter begin, Iter end) {
+    const size_t count = std::distance(begin, end);
+    MATHICGB_ASSERT(count <= capacity());
+    if (count > size())
+      resize(count);
+    std::copy(begin, end, mBegin);
+  }
+
+  /// There must be enough capacity for the new size.
+  void rawAssign(size_type count, const T& t) {
+    MATHICGB_ASSERT(count <= capacity());
+    if (count > size())
+      resize(count);
+    std::fill_n(begin(), count, t);
+  }
+
+  /// There must be enough capacity for the new size. This is why there is no
+  /// push_back and only a rawPushBack --- to remind you of the changed
+  /// contract.
+  void rawPushBack(const T& t) {
+    MATHICGB_ASSERT(size() < capacity());
+    new (mEnd) T(t);
+    ++mEnd;
+  }
+
+  void pop_back() {
+    MATHICGB_ASSERT(!empty());
+    mEnd->~T();
+    --mEnd;
+  }
+
+  void swap(RawVector<T>& v) {
+    std::swap(mBegin, v.mBegin);
+    std::swap(mEnd, v.mEnd);
+    std::swap(mCapacityEnd, v.mCapacityEnd);
+  }
+
+  void clear() {
+    while (!empty())
+      pop_back();
+  }
+
+  // **** Extra functionality not available on std::vector
+
+  // memcpy onto the end of the vector.
+  void memcpy(const T* from, size_t countOfT) {
+    MATHICGB_ASSERT(countOfT <= capacityToGo());
+    std::memcpy(mEnd, from, countOfT * sizeof(T));
+    mEnd += countOfT;
+  }
+
+  /// Unused capacity.
+  size_t capacityToGo() const {
+    return mCapacityEnd - mEnd;
+  }
+
+  /// Returns true if there is no more capacity left. That is, if
+  /// capacity() == size().
+  bool atCapacity() const {
+    return mEnd == mCapacityEnd;
+  }
+
+  /// Sets this object to its null state without destructing memory. Returns
+  /// a pointer to the previous beginning of the buffer.
+  pointer releaseMemory() {
+    const auto oldBegin = mBegin;
+    mBegin = 0;
+    mEnd = 0;
+    mCapacityEnd = 0;
+    return oldBegin;
+  }
+
+  /// Takes over the new memory that is passed in, copies the old values to the
+  /// new memory and destructs the old values. Returns a pointer to the previous
+  /// beginning of the buffer.
+  pointer setMemoryAndCopy(
+    pointer begin,
+    pointer capacityEnd
+  ) {
+    MATHICGB_ASSERT(size() <=
+      static_cast<size_type>(std::distance(begin, capacityEnd)));
+    const auto oldBegin = mBegin;
+    const auto end = std::copy(mBegin, mEnd, begin);
+    *this = RawVector<T>(begin, end, capacityEnd);
+    return oldBegin;
+  }
+
+  /// Takes over the new memory that is passed in without destructing memory.
+  /// Returns a pointer to the previous beginning of the buffer.
+  pointer releaseAndSetMemory(
+    pointer begin,
+    pointer end,
+    pointer capacityEnd
+  ) {
+    const auto oldBegin = mBegin;
+    mBegin = begin;
+    mEnd = end;
+    mCapacityEnd = capacityEnd;
+    return oldBegin;
+  }
+
+  /// Destructs memory and then takes over the new memory that is passed in.
+  /// Does not deallocate the backing memory. Returns a pointer to the previous
+  /// beginning of the buffer.
+  pointer clearAndSetMemory(
+    pointer begin,
+    pointer end,
+    pointer capacityEnd
+  ) {
+    clear();
+    const auto oldBegin = mBegin;
+    mBegin = begin;
+    mEnd = end;
+    mCapacityEnd = capacityEnd;
+    return oldBegin;
+  }
+
+private:
+  T* mBegin;
+  T* mEnd;
+  T* mCapacityEnd;
+};
+
+namespace std {
+  template<class T>
+  void swap(RawVector<T>& a, RawVector<T>& b) {
+    a.swap(b);
+  }
+}
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/Reducer.cpp b/src/mathicgb/Reducer.cpp
index ed344cf..a06a7b4 100755
--- a/src/mathicgb/Reducer.cpp
+++ b/src/mathicgb/Reducer.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "Reducer.hpp"
 
@@ -15,11 +17,12 @@
 #include "ReducerHash.hpp"
 #include "ReducerHashPack.hpp"
 #include "F4Reducer.hpp"
-
 #include "SigPolyBasis.hpp"
 #include <iostream>
 #include <algorithm>
 
+MATHICGB_NAMESPACE_BEGIN
+
 Reducer::Reducer():
   stats_maxsize(0),
   stats_maxsize_live(0),
@@ -199,7 +202,4 @@ Reducer::Stats::Stats():
 void Reducer::dump() const {
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/Reducer.hpp b/src/mathicgb/Reducer.hpp
index fcdcbda..81a5e2d 100755
--- a/src/mathicgb/Reducer.hpp
+++ b/src/mathicgb/Reducer.hpp
@@ -1,13 +1,15 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _Reducer_h_
-#define _Reducer_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_REDUCER_GUARD
+#define MATHICGB_REDUCER_GUARD
 
 #include "PolyRing.hpp"
 #include "Poly.hpp"
 #include <memtailor.h>
 #include <memory>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class SigPolyBasis;
 class PolyBasis;
 
@@ -164,9 +166,5 @@ protected:
   Stats mClassicStats;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/ReducerDedup.hpp b/src/mathicgb/ReducerDedup.hpp
index 46f08fa..d194266 100755
--- a/src/mathicgb/ReducerDedup.hpp
+++ b/src/mathicgb/ReducerDedup.hpp
@@ -1,13 +1,14 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
-#ifndef _reducer_dedup_h_
-#define _reducer_dedup_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_REDUCER_DEDUP_GUARD
+#define MATHICGB_REDUCER_DEDUP_GUARD
 
+#include "TypicalReducer.hpp"
+#include "ReducerHelper.hpp"
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
+MATHICGB_NAMESPACE_BEGIN
 
 template<template<typename ConfigType> class Queue> class ReducerDedup;
 
@@ -181,10 +182,5 @@ size_t ReducerDedup<Q>::getMemoryUse() const
   return TypicalReducer::getMemoryUse() + mQueue.getMemoryUse();
 }
 
-
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/ReducerHash.hpp b/src/mathicgb/ReducerHash.hpp
index 098b306..0db8685 100755
--- a/src/mathicgb/ReducerHash.hpp
+++ b/src/mathicgb/ReducerHash.hpp
@@ -1,14 +1,15 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
-#ifndef _reducer_hash_h_
-#define _reducer_hash_h_
-
-#include <memtailor.h>
-#include <mathic.h>
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_REDUCER_HASH_GUARD
+#define MATHICGB_REDUCER_HASH_GUARD
 
 #include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
 #include "PolyHashTable.hpp"
+#include <memtailor.h>
+#include <mathic.h>
+
+MATHICGB_NAMESPACE_BEGIN
 
 template<template<typename ConfigType> class Queue> class ReducerHash;
 
@@ -179,9 +180,5 @@ size_t ReducerHash<Q>::getMemoryUse() const
   return result;
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/ReducerHashPack.hpp b/src/mathicgb/ReducerHashPack.hpp
index 53ca579..c965a94 100755
--- a/src/mathicgb/ReducerHashPack.hpp
+++ b/src/mathicgb/ReducerHashPack.hpp
@@ -1,14 +1,15 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
-#ifndef _reducer_hash_pack_h
-#define _reducer_hash_pack_h
-
-#include <mathic.h>
-#include <memtailor.h>
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_REDUCER_HASH_PACK_GUARD
+#define MATHICGB_REDUCER_HASH_PACK_GUARD
 
 #include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
 #include "PolyHashTable.hpp"
+#include <mathic.h>
+#include <memtailor.h>
+
+MATHICGB_NAMESPACE_BEGIN
 
 template<template<typename ConfigType> class Queue> class ReducerHashPack;
 
@@ -276,9 +277,5 @@ size_t ReducerHashPack<Q>::getMemoryUse() const
     mHashTable.getMemoryUse();
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/ReducerHelper.hpp b/src/mathicgb/ReducerHelper.hpp
old mode 100644
new mode 100755
index c604f23..f32f190
--- a/src/mathicgb/ReducerHelper.hpp
+++ b/src/mathicgb/ReducerHelper.hpp
@@ -1,11 +1,15 @@
-#ifndef _reducer_helper_h_
-#define _reducer_helper_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_REDUCER_HELPER_GUARD
+#define MATHICGB_REDUCER_HELPER_GUARD
 
 // This namespace contains functions and classees that are useful for
 // writing subclasses of Reducer.
 
 #include "PolyRing.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 namespace ReducerHelper {
   // ************** Configurations **********************
 
@@ -84,9 +88,5 @@ namespace ReducerHelper {
 
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/ReducerNoDedup.hpp b/src/mathicgb/ReducerNoDedup.hpp
index 630d5d5..e4634e6 100755
--- a/src/mathicgb/ReducerNoDedup.hpp
+++ b/src/mathicgb/ReducerNoDedup.hpp
@@ -1,13 +1,14 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
-#ifndef _reducer_nodedup_h_
-#define _reducer_nodedup_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_REDUCER_NO_DEDUP_GUARD
+#define MATHICGB_REDUCER_NO_DEDUP_GUARD
 
+#include "TypicalReducer.hpp"
+#include "ReducerHelper.hpp"
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
+MATHICGB_NAMESPACE_BEGIN
 
 template<template<typename ConfigType> class Queue> class ReducerNoDedup;
 
@@ -175,10 +176,5 @@ size_t ReducerNoDedup<Q>::getMemoryUse() const
   return TypicalReducer::getMemoryUse() + mQueue.getMemoryUse();
 }
 
-
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/ReducerPack.hpp b/src/mathicgb/ReducerPack.hpp
index a1d7c3c..97984f9 100755
--- a/src/mathicgb/ReducerPack.hpp
+++ b/src/mathicgb/ReducerPack.hpp
@@ -1,13 +1,14 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
-#ifndef _reducer_pack_h_
-#define _reducer_pack_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_REDUCER_PACK_GUARD
+#define MATHICGB_REDUCER_PACK_GUARD
 
+#include "TypicalReducer.hpp"
+#include "ReducerHelper.hpp"
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
+MATHICGB_NAMESPACE_BEGIN
 
 template<template<typename> class Queue>
 class ReducerPack : public TypicalReducer {
@@ -238,9 +239,5 @@ size_t ReducerPack<Q>::getMemoryUse() const
     mPool.getMemoryUse();
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/ReducerPackDedup.hpp b/src/mathicgb/ReducerPackDedup.hpp
index 07776b6..f27f78f 100755
--- a/src/mathicgb/ReducerPackDedup.hpp
+++ b/src/mathicgb/ReducerPackDedup.hpp
@@ -1,13 +1,14 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
-#ifndef _reducer_pack_dedup_h_
-#define _reducer_pack_dedup_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_REDUCER_PACK_DEDUP_GUARD
+#define MATHICGB_REDUCER_PACK_DEDUP_GUARD
 
+#include "TypicalReducer.hpp"
+#include "ReducerHelper.hpp"
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
+MATHICGB_NAMESPACE_BEGIN
 
 template<template<typename> class Queue>
 class ReducerPackDedup : public TypicalReducer {
@@ -297,10 +298,5 @@ size_t ReducerPackDedup<Q>::getMemoryUse() const
     mPool.getMemoryUse();
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
-
diff --git a/src/mathicgb/SPairs.cpp b/src/mathicgb/SPairs.cpp
index b9ce010..6551e71 100755
--- a/src/mathicgb/SPairs.cpp
+++ b/src/mathicgb/SPairs.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "SPairs.hpp"
 
@@ -25,6 +27,8 @@ MATHICGB_DEFINE_LOG_DOMAIN(
 MATHICGB_DEFINE_LOG_ALIAS("SPairs", "SPairEarly,SPairLate");
 MATHICGB_DEFINE_LOG_ALIAS("SPairsDetail", "SPairs,SPairDegree,SPairLcm");
 
+MATHICGB_NAMESPACE_BEGIN
+
 SPairs::SPairs(const PolyBasis& basis, bool preferSparseSPairs):
   mMonoid(basis.ring().monoid()),
   mOrderMonoid(OrderMonoid::create(mMonoid)),
@@ -679,3 +683,5 @@ void SPairs::QueueConfiguration::computePairData(
   orderMonoid().lcm(monoid(), leadA, monoid(), leadB, orderBy);
   return; //todo: return true;
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/SPairs.hpp b/src/mathicgb/SPairs.hpp
index c37b373..bbd911b 100755
--- a/src/mathicgb/SPairs.hpp
+++ b/src/mathicgb/SPairs.hpp
@@ -1,11 +1,15 @@
-#ifndef _s_pairs_h_
-#define _s_pairs_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_S_PAIRS_GUARD
+#define MATHICGB_S_PAIRS_GUARD
 
 #include "PolyBasis.hpp"
 #include <utility>
 #include <mathic.h>
 #include <memory>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class PolyBasis;
 
 // Stores the set of pending S-pairs for use in the classic Buchberger
@@ -252,32 +256,35 @@ private:
     (OrderMonoid::Mono*, Index, Index, QueueConfiguration&);
 };
 
+MATHICGB_NAMESPACE_END
+
 namespace mathic {
   namespace PairQueueNamespace {
-	template<>
-	inline void constructPairData<SPairs::QueueConfiguration>(
+    template<>
+    inline void constructPairData<mgb::SPairs::QueueConfiguration>(
       void* memory,
       const Index col,
       const Index row,
-      SPairs::QueueConfiguration& conf
+      mgb::SPairs::QueueConfiguration& conf
     ) {
-	  MATHICGB_ASSERT(memory != 0);
-	  MATHICGB_ASSERT(col > row);
-	  auto pd = new (memory) SPairs::OrderMonoid::Mono(conf.allocPairData());
-	  conf.computePairData(col, row, *pd);
-	}
-
-	template<>
-	inline void destructPairData(
-      SPairs::OrderMonoid::Mono* pd,
+      MATHICGB_ASSERT(memory != 0);
+      MATHICGB_ASSERT(col > row);
+      auto pd = new (memory)
+        mgb::SPairs::OrderMonoid::Mono(conf.allocPairData());
+      conf.computePairData(col, row, *pd);
+    }
+    
+    template<>
+    inline void destructPairData(
+      mgb::SPairs::OrderMonoid::Mono* pd,
       const Index col,
       const Index row,
-      SPairs::QueueConfiguration& conf
+      mgb::SPairs::QueueConfiguration& conf
     ) {
-	  MATHICGB_ASSERT(pd != 0);
-	  MATHICGB_ASSERT(col > row);
-	  conf.freePairData(std::move(*pd));
-	}	
+      MATHICGB_ASSERT(pd != 0);
+      MATHICGB_ASSERT(col > row);
+      conf.freePairData(std::move(*pd));
+    }	
   }
 }
 
diff --git a/src/mathicgb/Scanner.cpp b/src/mathicgb/Scanner.cpp
index cc67dff..5d8ec09 100755
--- a/src/mathicgb/Scanner.cpp
+++ b/src/mathicgb/Scanner.cpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "Scanner.hpp"
 
@@ -6,6 +8,8 @@
 #include <sstream>
 #include <cstring>
 
+MATHICGB_NAMESPACE_BEGIN
+
 static const size_t BufferSize =
 #ifdef MATHICGB_DEBUG
   1;
@@ -182,3 +186,5 @@ bool Scanner::readBuffer(size_t minRead) {
 
   return didReadCount >= minRead;
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/Scanner.hpp b/src/mathicgb/Scanner.hpp
index fdbdc0f..d529ae9 100755
--- a/src/mathicgb/Scanner.hpp
+++ b/src/mathicgb/Scanner.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_SCANNER_GUARD
 #define MATHICGB_SCANNER_GUARD
 
@@ -11,6 +13,8 @@
 #include <sstream>
 #include <istream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 /// This class offers an input interface which is more convenient and
 /// often more efficient than dealing with a FILE* or std::istream
 /// directly. It keeps track of the current line number to report
@@ -270,4 +274,5 @@ bool Scanner::matchReadIntegerNoSign(T& t, bool negate) {
     return false;
 }
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/ScopeExit.hpp b/src/mathicgb/ScopeExit.hpp
index 5ca876a..2cb7f81 100755
--- a/src/mathicgb/ScopeExit.hpp
+++ b/src/mathicgb/ScopeExit.hpp
@@ -1,98 +1,104 @@
-#ifndef MATHICGB_SCOPE_EXIT_GUARD
-#define MATHICGB_SCOPE_EXIT_GUARD
-
-// Guard holds an action to call and calls it unless it has been released.
-template<class T>
-class Guard {
-public:
-  ~Guard() {
-    if (mOwning && mActive)
-      mAction();
-  }
-
-private:
-  friend struct GuardMaker;
-  Guard(T&& action, const bool& active):
-    mAction(std::move(action)), mOwning(true), mActive(active) {}
-
-  // Most compilers should elide the call to this construtor, but it must be
-  // here anyway and we should support even a crazy compiler that decides to
-  // call it.
-  Guard(Guard<T>&& guard):
-    mAction(std::move(guard.mAction)), mOwning(true), mActive(guard.mActive)
-  {
-    assert(guard.mActive);
-    guard.mOwning = false; // to avoid calling mAction twice
-  }
-
-  bool mOwning;
-  const bool& mActive;
-  const T mAction;
-};
-
-// The class user code interacts with to dismiss an action.
-class Dismisser {
-public:
-  Dismisser(bool& active): mActive(active) {}
-  void dismiss() {mActive = false;}
-
-private:
-  bool& mActive;
-};
-
-// Helper class that allows convenient syntax for the macro by overloading
-// operator+.
-struct GuardMaker {
-public:
-  GuardMaker(const bool& active): mActive(active) {}
-
-  template<class T>
-  Guard<T> operator+(T&& t) {return Guard<T>(std::forward<T>(t), mActive);}
-
-private:
-  const bool& mActive;
-};
-
-#define MYLIB__CAT_HELPER(A, B) A##B
-#define MYLIB__CAT(A, B) MYLIB__CAT_HELPER(A, B)
-#define MYLIB__UNIQUE(NAME) MYLIB__CAT(MyLib_,MYLIB__CAT(NAME,__LINE__))
-
-// Example, with no need to dismiss:
-//   FILE* file = fopen("file.txt", "r");
-//   MATHICGB_SCOPE_EXIT() {
-//     fclose(file);
-//     std::cout << "file closed";
-//   };
-//   // ...
-//   return; // the file is closed
-//
-// Example, with need to dismiss:
-//   v.push_back(5);
-//   MATHICGB_SCOPE_EXIT(name) {v.pop_back();};
-//   // ...
-//   if (error)
-//     return; // the pop_back is done
-//   name.dismiss();
-//   return; // the pop_back is not done
-//
-// The middle line is a no-op if the name parameter expands to nothing.
-// When NAME expands to nothing, we need the static_cast to prevent
-// the compiler from parsing the middle line as a redeclaration of
-// myBool. In the final line we use that a const reference keeps
-// temporary objects alive until the end of the scope. It would be correct
-// to copy, but this way we can keep the copy constructor private
-// and help out any compiler that has issue with eliding that copy.
-#define MATHICGB_SCOPE_EXIT(NAME) \
-  bool MYLIB__UNIQUE(active) = true; \
-  ::Dismisser NAME(static_cast<bool&>(MYLIB__UNIQUE(active))); \
-  const auto& MYLIB__UNIQUE(guard) = \
-    ::GuardMaker(MYLIB__UNIQUE(active)) + [&]
-
-// Without this pragma, MSVC will say
-//  warning C4003: not enough actual parameters for macro 'MYLIB_SCOPE_EXIT'
-// when using MYLIB_SCOPE_EXIT without a name parameter. Not very happy about
-// turning off the warning. I wonder if there is a way to avoid the warning in
-// this case without turning it off.
-#pragma warning (disable: 4003)
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_SCOPE_EXIT_GUARD
+#define MATHICGB_SCOPE_EXIT_GUARD
+
+MATHICGB_NAMESPACE_BEGIN
+
+// Guard holds an action to call and calls it unless it has been released.
+template<class T>
+class Guard {
+public:
+  ~Guard() {
+    if (mOwning && mActive)
+      mAction();
+  }
+
+private:
+  friend struct GuardMaker;
+  Guard(T&& action, const bool& active):
+    mAction(::std::move(action)), mOwning(true), mActive(active) {}
+
+  // Most compilers should elide the call to this construtor, but it must be
+  // here anyway and we should support even a crazy compiler that decides to
+  // call it.
+  Guard(Guard<T>&& guard):
+    mAction(::std::move(guard.mAction)), mOwning(true), mActive(guard.mActive)
+  {
+    assert(guard.mActive);
+    guard.mOwning = false; // to avoid calling mAction twice
+  }
+
+  bool mOwning;
+  const bool& mActive;
+  const T mAction;
+};
+
+// The class user code interacts with to dismiss an action.
+class Dismisser {
+public:
+  Dismisser(bool& active): mActive(active) {}
+  void dismiss() {mActive = false;}
+
+private:
+  bool& mActive;
+};
+
+// Helper class that allows convenient syntax for the macro by overloading
+// operator+.
+struct GuardMaker {
+public:
+  GuardMaker(const bool& active): mActive(active) {}
+
+  template<class T>
+  Guard<T> operator+(T&& t) {return Guard<T>(::std::forward<T>(t), mActive);}
+
+private:
+  const bool& mActive;
+};
+
+MATHICGB_NAMESPACE_END
+
+#define MYLIB__CAT_HELPER(A, B) A##B
+#define MYLIB__CAT(A, B) MYLIB__CAT_HELPER(A, B)
+#define MYLIB__UNIQUE(NAME) MYLIB__CAT(MyLib_,MYLIB__CAT(NAME,__LINE__))
+
+// Example, with no need to dismiss:
+//   FILE* file = fopen("file.txt", "r");
+//   MATHICGB_SCOPE_EXIT() {
+//     fclose(file);
+//     ::std::cout << "file closed";
+//   };
+//   // ...
+//   return; // the file is closed
+//
+// Example, with need to dismiss:
+//   v.push_back(5);
+//   MATHICGB_SCOPE_EXIT(name) {v.pop_back();};
+//   // ...
+//   if (error)
+//     return; // the pop_back is done
+//   name.dismiss();
+//   return; // the pop_back is not done
+//
+// The middle line is a no-op if the name parameter expands to nothing.
+// When NAME expands to nothing, we need the static_cast to prevent
+// the compiler from parsing the middle line as a redeclaration of
+// myBool. In the final line we use that a const reference keeps
+// temporary objects alive until the end of the scope. It would be correct
+// to copy, but this way we can keep the copy constructor private
+// and help out any compiler that has issue with eliding that copy.
+#define MATHICGB_SCOPE_EXIT(NAME) \
+  bool MYLIB__UNIQUE(active) = true; \
+  ::mgb::Dismisser NAME(static_cast<bool&>(MYLIB__UNIQUE(active)));    \
+  const auto& MYLIB__UNIQUE(guard) = \
+    ::mgb::GuardMaker(MYLIB__UNIQUE(active)) + [&]
+
+// Without this pragma, MSVC will say
+//  warning C4003: not enough actual parameters for macro 'MYLIB_SCOPE_EXIT'
+// when using MYLIB_SCOPE_EXIT without a name parameter. Not very happy about
+// turning off the warning. I wonder if there is a way to avoid the warning in
+// this case without turning it off.
+#pragma warning (disable: 4003)
+
+#endif
diff --git a/src/mathicgb/SigPolyBasis.cpp b/src/mathicgb/SigPolyBasis.cpp
index 8b1256d..f44551e 100755
--- a/src/mathicgb/SigPolyBasis.cpp
+++ b/src/mathicgb/SigPolyBasis.cpp
@@ -8,6 +8,8 @@
 #include <iostream>
 #include <iomanip>
 
+MATHICGB_NAMESPACE_BEGIN
+
 SigPolyBasis::SigPolyBasis(
   const PolyRing* R0,
   int divisorLookupType,
@@ -489,7 +491,4 @@ SigPolyBasis::StoredRatioCmp::~StoredRatioCmp() {
     mBasis.ring().freeMonomial(mTmp);
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/SigPolyBasis.hpp b/src/mathicgb/SigPolyBasis.hpp
index 225e571..ed3977a 100755
--- a/src/mathicgb/SigPolyBasis.hpp
+++ b/src/mathicgb/SigPolyBasis.hpp
@@ -11,6 +11,8 @@
 #include <vector>
 #include <set>
 
+MATHICGB_NAMESPACE_BEGIN
+
 #ifndef USE_RATIO_RANK
 #define USE_RATIO_RANK true
 #endif
@@ -247,9 +249,5 @@ inline int SigPolyBasis::StoredRatioCmp::compare(size_t be) const {
   }
 }
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/SigSPairQueue.cpp b/src/mathicgb/SigSPairQueue.cpp
index e5f2def..bfe97e5 100755
--- a/src/mathicgb/SigSPairQueue.cpp
+++ b/src/mathicgb/SigSPairQueue.cpp
@@ -1,8 +1,12 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "SigSPairQueue.hpp"
 
 #include "SigPolyBasis.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 SigSPairQueue::~SigSPairQueue() {}
 
 namespace {
@@ -152,24 +156,45 @@ private:
   mathic::PairQueueNamespace::DestructPairDataFunction<Configuration>;
 };
 
+std::unique_ptr<SigSPairQueue> SigSPairQueue::create(
+  SigPolyBasis const& basis
+) {
+  return make_unique<ConcreteSigSPairQueue>(basis);
+}
+
+MATHICGB_NAMESPACE_END
+
 namespace mathic {
   namespace PairQueueNamespace {
     template<>
-    struct ConstructPairDataFunction<ConcreteSigSPairQueue::Configuration> {
-      inline static void function
-      (void* memory, Index col, Index row, ConcreteSigSPairQueue::Configuration& conf) {
+    struct ConstructPairDataFunction
+      <mgb::ConcreteSigSPairQueue::Configuration>
+    {
+      inline static void function(
+        void* memory,
+        Index col,
+        Index row,
+        mgb::ConcreteSigSPairQueue::Configuration& conf
+      ) {
         MATHICGB_ASSERT(memory != 0);
         MATHICGB_ASSERT(col > row);
-        monomial* pd = new (memory) monomial
+        auto pd = new (memory)
+          mgb::ConcreteSigSPairQueue::Configuration::PairData
           (conf.basis().ring().allocMonomial());
         conf.computePairData(col, row, *pd);
       }
-	};
+    };
 
     template<>
-    struct DestructPairDataFunction<ConcreteSigSPairQueue::Configuration> {
-      inline static void function
-      (monomial* pd, Index col, Index row, ConcreteSigSPairQueue::Configuration& conf) {
+    struct DestructPairDataFunction
+      <mgb::ConcreteSigSPairQueue::Configuration>
+    {
+      inline static void function(
+        mgb::ConcreteSigSPairQueue::Configuration::PairData* pd,
+        Index col,
+        Index row,
+        mgb::ConcreteSigSPairQueue::Configuration& conf
+      ) {
         MATHICGB_ASSERT(pd != 0);
         MATHICGB_ASSERT(col > row);
         conf.basis().ring().freeMonomial(*pd);
@@ -177,9 +202,3 @@ namespace mathic {
     };
   }
 }
-
-std::unique_ptr<SigSPairQueue> SigSPairQueue::create(
-  SigPolyBasis const& basis
-) {
-  return make_unique<ConcreteSigSPairQueue>(basis);
-}
diff --git a/src/mathicgb/SigSPairQueue.hpp b/src/mathicgb/SigSPairQueue.hpp
index 0fb75ef..f745633 100755
--- a/src/mathicgb/SigSPairQueue.hpp
+++ b/src/mathicgb/SigSPairQueue.hpp
@@ -1,73 +1,78 @@
-#ifndef MATHICGB_SIG_S_PAIR_QUEUE_GUARD
-#define MATHICGB_SIG_S_PAIR_QUEUE_GUARD
-
-#include "PolyRing.hpp"
-#include <string>
-#include <vector>
-
-typedef unsigned short SmallIndex;
-typedef unsigned int BigIndex;
-
-struct PreSPair {
-  BigIndex i;
-  monomial signature;
-};
-
-class SigPolyBasis;
-
-// A priority queue on S-pairs where the priority is based on a
-// signature as in signature Grobner basis algorithms. The class is
-// not responsible for eliminating S-pairs or doing anything beyond
-// order the S-pairs.
-class SigSPairQueue {
-public:
-  typedef PolyRing::Monoid Monoid;
-
-  virtual ~SigSPairQueue();
-
-  typedef std::pair<size_t, size_t> Pair;
-  typedef std::vector<Pair> Pairs;
-  //typedef std::pair<size_t, monomial> IndexSig;
-  typedef PreSPair IndexSig;
-  typedef std::vector<IndexSig> IndexSigs;
-
-  // Takes the minimal signature in the queue and adds all S-pairs of
-  // that signature to pairs. Clears pairs first. Returns null and
-  // leaves pairs empty if the queue is empty.
-  //
-  // This class does not have an empty() method on purpose - you are
-  // supposed to call this method until it returns null.
-  virtual monomial popSignature(Pairs& pairs) = 0;
-
-  // If (x, sig) is an element of pairsConsumed then (pairWith, x) is
-  // added to the queue. sig must be the signature of the S-pair
-  // (pairWith, x).
-  //
-  // ATTENTION: the class to pushPairs must have pairWith in the
-  // sequence 0, 1, 2, 3 and so on. It follows from this that the
-  // queue can figure out what pairWith is without being told. Thus
-  // the purpose of pairWith is to make it possible to make an
-  // assertion saying that the caller and the queue agree on what
-  // pairWith is.
-  // 
-  // ATTENTION: pairsConsumed will be cleared and the signatures in it
-  // will be freed on the ring. This is because the queue will need to
-  // alter pairsConsumed in various ways and clearing it after that is
-  // cleaner than exposing what's being done to
-  // pairsConsumed. Especially since after you did pushPairs there
-  // would not be a reason to care about what its content was.
-  virtual void pushPairs(size_t pairWith, IndexSigs& pairsConsumed) = 0;
-
-  // Returns a string that describes the queue.
-  virtual std::string name() const = 0;
-
-  // Returns the number of pairs currently in the queue.
-  virtual size_t pairCount() const  = 0;
-
-  // Returns number of bytes of memory used.
-  virtual size_t memoryUse() const = 0;
-
-  static std::unique_ptr<SigSPairQueue> create(SigPolyBasis const& basis);
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_SIG_S_PAIR_QUEUE_GUARD
+#define MATHICGB_SIG_S_PAIR_QUEUE_GUARD
+
+#include "PolyRing.hpp"
+#include <string>
+#include <vector>
+
+MATHICGB_NAMESPACE_BEGIN
+
+typedef unsigned short SmallIndex;
+typedef unsigned int BigIndex;
+
+struct PreSPair {
+  BigIndex i;
+  monomial signature;
+};
+
+class SigPolyBasis;
+
+// A priority queue on S-pairs where the priority is based on a
+// signature as in signature Grobner basis algorithms. The class is
+// not responsible for eliminating S-pairs or doing anything beyond
+// order the S-pairs.
+class SigSPairQueue {
+public:
+  typedef PolyRing::Monoid Monoid;
+
+  virtual ~SigSPairQueue();
+
+  typedef std::pair<size_t, size_t> Pair;
+  typedef std::vector<Pair> Pairs;
+  //typedef std::pair<size_t, monomial> IndexSig;
+  typedef PreSPair IndexSig;
+  typedef std::vector<IndexSig> IndexSigs;
+
+  // Takes the minimal signature in the queue and adds all S-pairs of
+  // that signature to pairs. Clears pairs first. Returns null and
+  // leaves pairs empty if the queue is empty.
+  //
+  // This class does not have an empty() method on purpose - you are
+  // supposed to call this method until it returns null.
+  virtual monomial popSignature(Pairs& pairs) = 0;
+
+  // If (x, sig) is an element of pairsConsumed then (pairWith, x) is
+  // added to the queue. sig must be the signature of the S-pair
+  // (pairWith, x).
+  //
+  // ATTENTION: the class to pushPairs must have pairWith in the
+  // sequence 0, 1, 2, 3 and so on. It follows from this that the
+  // queue can figure out what pairWith is without being told. Thus
+  // the purpose of pairWith is to make it possible to make an
+  // assertion saying that the caller and the queue agree on what
+  // pairWith is.
+  // 
+  // ATTENTION: pairsConsumed will be cleared and the signatures in it
+  // will be freed on the ring. This is because the queue will need to
+  // alter pairsConsumed in various ways and clearing it after that is
+  // cleaner than exposing what's being done to
+  // pairsConsumed. Especially since after you did pushPairs there
+  // would not be a reason to care about what its content was.
+  virtual void pushPairs(size_t pairWith, IndexSigs& pairsConsumed) = 0;
+
+  // Returns a string that describes the queue.
+  virtual std::string name() const = 0;
+
+  // Returns the number of pairs currently in the queue.
+  virtual size_t pairCount() const  = 0;
+
+  // Returns number of bytes of memory used.
+  virtual size_t memoryUse() const = 0;
+
+  static std::unique_ptr<SigSPairQueue> create(SigPolyBasis const& basis);
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/SigSPairs.cpp b/src/mathicgb/SigSPairs.cpp
index d3b7b81..696075a 100755
--- a/src/mathicgb/SigSPairs.cpp
+++ b/src/mathicgb/SigSPairs.cpp
@@ -1,4 +1,5 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "SigSPairs.hpp"
 
@@ -9,6 +10,8 @@
 #include <stdexcept>
 #include <iostream>
 
+MATHICGB_NAMESPACE_BEGIN
+
 SigSPairs::SigSPairs(
   const PolyRing *R0,
   const SigPolyBasis *GB0,
@@ -317,7 +320,4 @@ size_t SigSPairs::getKnownSyzygyBitsMemoryUse() const {
   return mKnownSyzygyTri.getMemoryUse();
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/SigSPairs.hpp b/src/mathicgb/SigSPairs.hpp
index 94a37f4..7518ad9 100755
--- a/src/mathicgb/SigSPairs.hpp
+++ b/src/mathicgb/SigSPairs.hpp
@@ -1,6 +1,7 @@
-
-#ifndef _spair_handler_h_
-#define _spair_handler_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_SIG_S_PAIRS_GUARD
+#define MATHICGB_SIG_S_PAIRS_GUARD
 
 #include "PolyRing.hpp"
 #include "KoszulQueue.hpp"
@@ -9,6 +10,8 @@
 #include <memtailor.h>
 #include <vector>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class Poly;
 class MonomialTableArray;
 class SigPolyBasis;
@@ -127,9 +130,5 @@ private:
   mutable Stats mStats;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/SignatureGB.cpp b/src/mathicgb/SignatureGB.cpp
index 77f6524..c6ec1c0 100755
--- a/src/mathicgb/SignatureGB.cpp
+++ b/src/mathicgb/SignatureGB.cpp
@@ -1,4 +1,5 @@
-// Copyright 2011 Michael E. Stillman
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "SignatureGB.hpp"
 
@@ -9,6 +10,8 @@
 #include "MTArray.hpp"
 #include <mathic.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 int tracingLevel = 0;
 
 SignatureGB::SignatureGB(
@@ -729,7 +732,4 @@ unsigned long long SignatureGB::getSingularReductionCount() const {
   return reducer->sigStats().singularReductions;
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/SignatureGB.hpp b/src/mathicgb/SignatureGB.hpp
index 282fe8a..109ff5e 100755
--- a/src/mathicgb/SignatureGB.hpp
+++ b/src/mathicgb/SignatureGB.hpp
@@ -1,7 +1,7 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _sig_gb_h_
-#define _sig_gb_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_SIGNATURE_G_B_GUARD
+#define MATHICGB_SIGNATURE_G_B_GUARD
 
 #include "PolyRing.hpp"
 #include "MTArray.hpp"
@@ -13,6 +13,8 @@
 #include "MonoProcessor.hpp"
 #include <map>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class SigSPairs;
 class DivisorLookup;
 
@@ -104,9 +106,5 @@ private:
   std::unique_ptr<MonoProcessor<Monoid>> mProcessor;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/SparseMatrix.cpp b/src/mathicgb/SparseMatrix.cpp
index 14171d8..6a2afb7 100755
--- a/src/mathicgb/SparseMatrix.cpp
+++ b/src/mathicgb/SparseMatrix.cpp
@@ -1,15 +1,19 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "SparseMatrix.hpp"
 
 #include "Poly.hpp"
 #include <algorithm>
 
+MATHICGB_NAMESPACE_BEGIN
+
 void SparseMatrix::takeRowsFrom(SparseMatrix&& matrix) {
   if (matrix.mRows.empty())
     return;
 
   if (mRows.empty()) {
-    *this = std::move(matrix);
+    *this = ::std::move(matrix);
     return;
   }
 
@@ -20,8 +24,8 @@ void SparseMatrix::takeRowsFrom(SparseMatrix&& matrix) {
   if (mBlock.mHasNoRows) // only put mBlock in chain of blocks if non-empty
     oldestBlock->mPreviousBlock = mBlock.mPreviousBlock;
   else
-    oldestBlock->mPreviousBlock = new Block(std::move(mBlock));
-  mBlock = std::move(matrix.mBlock);
+    oldestBlock->mPreviousBlock = new Block(::std::move(mBlock));
+  mBlock = ::std::move(matrix.mBlock);
 
   mRows.insert(mRows.end(), matrix.mRows.begin(), matrix.mRows.end());
   matrix.clear();
@@ -29,7 +33,7 @@ void SparseMatrix::takeRowsFrom(SparseMatrix&& matrix) {
 
 void SparseMatrix::rowToPolynomial(
   const RowIndex row,
-  const std::vector<monomial>& colMonomials,
+  const ::std::vector<monomial>& colMonomials,
   Poly& poly
 ) {
   poly.setToZero();
@@ -47,7 +51,7 @@ void SparseMatrix::sortRowsByIncreasingPivots() {
   SparseMatrix ordered;
   const auto rowCount = this->rowCount();
 
-  std::vector<RowIndex> rows(rowCount);
+  ::std::vector<RowIndex> rows(rowCount);
   for (RowIndex row = 0; row < rowCount; ++row)
     rows[row] = row;
 
@@ -66,16 +70,16 @@ void SparseMatrix::sortRowsByIncreasingPivots() {
     }
     return aIt == aEnd && bIt != bEnd;
   };
-  std::sort(rows.begin(), rows.end(), lexLess);
+  ::std::sort(rows.begin(), rows.end(), lexLess);
 
   // construct ordered with pivot columns in increasing order
   ordered.clear();
   for (size_t i = 0; i < rowCount; ++i)
     ordered.appendRow(*this, rows[i]);
-  *this = std::move(ordered);
+  *this = ::std::move(ordered);
 }
 
-void SparseMatrix::applyColumnMap(const std::vector<ColIndex>& colMap) {
+void SparseMatrix::applyColumnMap(const ::std::vector<ColIndex>& colMap) {
   MATHICGB_ASSERT(colMap.size() >= computeColCount());
   Block* block = &mBlock;
   for (; block != 0; block = block->mPreviousBlock) {
@@ -96,7 +100,7 @@ void SparseMatrix::multiplyRow(
     it.setScalar(modularProduct(it.scalar(), multiplier, modulus));
 }
 
-void SparseMatrix::print(std::ostream& out) const {
+void SparseMatrix::print(::std::ostream& out) const {
   if (rowCount() == 0)
     out << "matrix with no rows\n";
   for (RowIndex row = 0; row < rowCount(); ++row) {
@@ -108,7 +112,7 @@ void SparseMatrix::print(std::ostream& out) const {
   }
 }
 
-void SparseMatrix::printStatistics(std::ostream& out) const {
+void SparseMatrix::printStatistics(::std::ostream& out) const {
   typedef mathic::ColumnPrinter ColPr;
 
   ColPr pr;
@@ -139,8 +143,8 @@ void SparseMatrix::printStatistics(std::ostream& out) const {
   out << '\n' << pr << "\n";
 }
 
-std::string SparseMatrix::toString() const {
-  std::ostringstream out;
+::std::string SparseMatrix::toString() const {
+  ::std::ostringstream out;
   print(out);
   return out.str();
 }
@@ -199,7 +203,7 @@ SparseMatrix& SparseMatrix::operator=(const SparseMatrix& matrix) {
 
 void SparseMatrix::swap(SparseMatrix& matrix) {
   mBlock.swap(matrix.mBlock);
-  using std::swap;
+  using ::std::swap;
   swap(mRows, matrix.mRows);
   swap(mMemoryQuantum, matrix.mMemoryQuantum);
 }
@@ -228,7 +232,7 @@ SparseMatrix::ColIndex SparseMatrix::computeColCount() const {
   for (RowIndex row = 0; row < rowCount(); ++row) {
     const auto end = rowEnd(row);
     for (auto it = rowBegin(row); it != end; ++it)
-      colCount = std::max(colCount, it.index() + 1);
+      colCount = ::std::max(colCount, it.index() + 1);
   }
   return colCount;
 }
@@ -249,7 +253,7 @@ void SparseMatrix::clear() {
 }
 
 void SparseMatrix::appendRowWithModulus(
-  std::vector<uint64> const& v,
+  ::std::vector<uint64> const& v,
   const Scalar modulus
 ) {
   const auto count = static_cast<ColIndex>(v.size());
@@ -262,7 +266,7 @@ void SparseMatrix::appendRowWithModulus(
 }
 
 void SparseMatrix::appendRowWithModulusNormalized(
-  std::vector<uint64> const& v,
+  ::std::vector<uint64> const& v,
   const Scalar modulus
 ) {
   uint16 multiply = 1; 
@@ -286,7 +290,7 @@ void SparseMatrix::appendRowWithModulusNormalized(
 }
 
 bool SparseMatrix::appendRowWithModulusIfNonZero(
-  std::vector<uint64> const& v,
+  ::std::vector<uint64> const& v,
   const Scalar modulus
 ) {
   appendRowWithModulus(v, modulus);
@@ -317,12 +321,12 @@ void SparseMatrix::reserveFreeEntries(const size_t freeCount) {
   const size_t count = freeCount + ( // todo: detect overflow for this addition
     mBlock.mHasNoRows ?
     mBlock.mColIndices.size() :
-    std::distance(mRows.back().mIndicesEnd, mBlock.mColIndices.end())
+    ::std::distance(mRows.back().mIndicesEnd, mBlock.mColIndices.end())
   );
 
   // @todo: fix memory leaks on exception
 
-  auto oldBlock = new Block(std::move(mBlock));
+  auto oldBlock = new Block(::std::move(mBlock));
   MATHICGB_ASSERT(mBlock.mColIndices.begin() == 0);
   MATHICGB_ASSERT(mBlock.mScalars.begin() == 0);
   MATHICGB_ASSERT(mBlock.mHasNoRows);
@@ -356,9 +360,9 @@ void SparseMatrix::reserveFreeEntries(const size_t freeCount) {
     // remove the pending entries from old block so that counting the number
     // of entries will give the correct result in future.
     oldBlock->mColIndices.resize
-      (std::distance(oldBlock->mColIndices.begin(), mRows.back().mIndicesEnd));
+      (::std::distance(oldBlock->mColIndices.begin(), mRows.back().mIndicesEnd));
     oldBlock->mScalars.resize
-      (std::distance(oldBlock->mScalars.begin(), mRows.back().mScalarsEnd));      
+      (::std::distance(oldBlock->mScalars.begin(), mRows.back().mScalarsEnd));      
     mBlock.mPreviousBlock = oldBlock;
   }
 }
@@ -423,7 +427,7 @@ size_t SparseMatrix::Block::memoryUseTrimmed() const {
   return mColIndices.memoryUseTrimmed() + mScalars.memoryUseTrimmed();
 }
 
-std::ostream& operator<<(std::ostream& out, const SparseMatrix& matrix) {
+::std::ostream& operator<<(::std::ostream& out, const SparseMatrix& matrix) {
   matrix.print(out);
   return out;
 }
@@ -444,7 +448,7 @@ namespace {
   }
 
   template<class T>
-  void writeMany(const std::vector<T>& v, FILE* file) {
+  void writeMany(const ::std::vector<T>& v, FILE* file) {
     if (v.empty())
       return;
     if (fwrite(v.data(), sizeof(T), v.size(), file) != v.size())
@@ -452,7 +456,7 @@ namespace {
   }
 
   template<class T>
-  void readMany(FILE* file, size_t count, std::vector<T>& v) {
+  void readMany(FILE* file, size_t count, ::std::vector<T>& v) {
     size_t const originalSize = v.size();
     v.resize(originalSize + count);
     if (fread(v.data() + originalSize, sizeof(T), count, file) != count)
@@ -483,7 +487,7 @@ void SparseMatrix::write(const Scalar modulus, FILE* file) const {
       mathic::reportError("error while writing to file.");
   }
 
-  std::vector<uint32> entryCounts;
+  ::std::vector<uint32> entryCounts;
   for (SparseMatrix::RowIndex row = 0; row < storedRowCount; ++row)
     entryCounts.push_back(entryCountInRow(row));
   writeMany<uint32>(entryCounts, file);
@@ -508,22 +512,22 @@ SparseMatrix::Scalar SparseMatrix::read(FILE* file) {
   // Read scalars.
   {
     mBlock.mScalars.resize(entryCount);
-    std::vector<uint16> scalars;
+    ::std::vector<uint16> scalars;
     readMany(file, entryCount, scalars);
-    std::copy(scalars.begin(), scalars.end(), mBlock.mScalars.begin());
+    ::std::copy(scalars.begin(), scalars.end(), mBlock.mScalars.begin());
   }
 
   // Read column indices.
   {
     mBlock.mColIndices.resize(entryCount);
-    std::vector<uint32> indices;
+    ::std::vector<uint32> indices;
     readMany(file, entryCount, indices);
-    std::copy(indices.begin(), indices.end(), mBlock.mColIndices.begin());
+    ::std::copy(indices.begin(), indices.end(), mBlock.mColIndices.begin());
   }
 
   // Read where rows begin and end.
   {
-    std::vector<uint32> sizes;
+    ::std::vector<uint32> sizes;
     readMany(file, rowCount, sizes);
     uint32 runningOffset = 0;
     for (auto it = sizes.begin(); it != sizes.end(); ++it) {
@@ -551,7 +555,7 @@ void SparseMatrix::writePBM(FILE* file) {
 
   // Write PBM header
   {
-    std::stringstream out;
+    ::std::stringstream out;
     out << "P1 " << colCount << ' ' << rowCount << '\n';
     fputs(out.str().c_str(), file);
   }
@@ -594,3 +598,5 @@ bool SparseMatrix::debugAssertValid() const {
   }
   return true;
 }
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/SparseMatrix.hpp b/src/mathicgb/SparseMatrix.hpp
index bbeef08..1ef19f6 100755
--- a/src/mathicgb/SparseMatrix.hpp
+++ b/src/mathicgb/SparseMatrix.hpp
@@ -1,3 +1,5 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #ifndef MATHICGB_SPARSE_MATRIX_GUARD
 #define MATHICGB_SPARSE_MATRIX_GUARD
 
@@ -10,6 +12,9 @@
 #include <sstream>
 #include <string>
 #include <iterator>
+
+MATHICGB_NAMESPACE_BEGIN
+
 class Poly;
 
 /** A class that implements a sparse matrix.
@@ -54,15 +59,15 @@ public:
   {}
 
   SparseMatrix(SparseMatrix&& matrix):
-    mRows(std::move(matrix.mRows)),
-    mBlock(std::move(matrix.mBlock)),
+    mRows(::std::move(matrix.mRows)),
+    mBlock(::std::move(matrix.mBlock)),
     mMemoryQuantum(matrix.mMemoryQuantum)
   {
   }
 
   SparseMatrix& operator=(SparseMatrix&& matrix) {
     this->~SparseMatrix();
-    new (this) SparseMatrix(std::move(matrix));
+    new (this) SparseMatrix(::std::move(matrix));
     return *this;
   }
 
@@ -154,11 +159,11 @@ public:
 
   /// Prints the matrix in a human readable format to out.
   /// Useful for debugging.
-  void print(std::ostream& out) const;
+  void print(::std::ostream& out) const;
 
-  void printStatistics(std::ostream& out) const;
+  void printStatistics(::std::ostream& out) const;
 
-  std::string toString() const;
+  ::std::string toString() const;
 
   /// Removes the leading trimThisMany columns. The columns are
   /// removed by replacing all column indices col by col -
@@ -217,26 +222,26 @@ public:
   
   void appendRow(const SparseMatrix& matrix, RowIndex row);
 
-  void appendRowWithModulus(const std::vector<uint64>& v, Scalar modulus);
+  void appendRowWithModulus(const ::std::vector<uint64>& v, Scalar modulus);
   
   template<class T>
-  void appendRow(const std::vector<T>& v, ColIndex leadCol = 0);
+  void appendRow(const ::std::vector<T>& v, ColIndex leadCol = 0);
 
-  void appendRowWithModulusNormalized(const std::vector<uint64>& v, Scalar modulus);
+  void appendRowWithModulusNormalized(const ::std::vector<uint64>& v, Scalar modulus);
 
   // Returns true if the row was non-zero. Otherwise the row was not
   // appended.
-  bool appendRowWithModulusIfNonZero(const std::vector<uint64>& v, Scalar modulus);
+  bool appendRowWithModulusIfNonZero(const ::std::vector<uint64>& v, Scalar modulus);
 
   /// Replaces all column indices i with colMap[i].
-  void applyColumnMap(const std::vector<ColIndex>& colMap);
+  void applyColumnMap(const ::std::vector<ColIndex>& colMap);
 
   void multiplyRow(RowIndex row, Scalar multiplier, Scalar modulus);
 
   /// Let poly be the dot product of colMonomials and the given row.
   void rowToPolynomial(
     RowIndex row,
-    const std::vector<monomial>& colMonomials,
+    const ::std::vector<monomial>& colMonomials,
     Poly& poly);
 
   /// Reorders the rows so that the index of the leading column in
@@ -257,12 +262,12 @@ public:
   /// Iterates through the entries in a row.
   class ConstRowIterator {
   public:
-    typedef const std::pair<ColIndex, Scalar> value_type;
+    typedef const ::std::pair<ColIndex, Scalar> value_type;
 	typedef ptrdiff_t difference_type;
     typedef size_t distance_type;
     typedef value_type* pointer;
     typedef value_type& reference;
-    typedef std::random_access_iterator_tag iterator_category;
+    typedef ::std::random_access_iterator_tag iterator_category;
 
     ConstRowIterator& operator++() {
       ++mScalarIt;
@@ -312,12 +317,12 @@ public:
   /// Iterates through the entries in a row.
   class RowIterator {
   public:
-    typedef const std::pair<ColIndex, Scalar> value_type;
+    typedef const ::std::pair<ColIndex, Scalar> value_type;
 	typedef ptrdiff_t difference_type;
     typedef size_t distance_type;
     typedef value_type* pointer;
     typedef value_type& reference;
-    typedef std::random_access_iterator_tag iterator_category;
+    typedef ::std::random_access_iterator_tag iterator_category;
 
     RowIterator& operator++() {
       ++mScalarIt;
@@ -383,20 +388,20 @@ private:
 
     bool empty() const {return mIndicesBegin == mIndicesEnd;}
     ColIndex size() const {
-      return static_cast<ColIndex>(std::distance(mIndicesBegin, mIndicesEnd));
+      return static_cast<ColIndex>(::std::distance(mIndicesBegin, mIndicesEnd));
     }
   };
-  std::vector<Row> mRows;
+  ::std::vector<Row> mRows;
 
   /// Memory is allocated a block at a time. This avoids the need for copying
-  /// that a std::vector normally does on reallocation. Believe it or not,
+  /// that a ::std::vector normally does on reallocation. Believe it or not,
   /// copying sparse matrix memory due to reallocation was accounting for 5%
   /// of the running time before this change.
   struct Block {
     Block(): mPreviousBlock(0), mHasNoRows(true) {}
     Block(Block&& block):
-      mColIndices(std::move(block.mColIndices)),
-      mScalars(std::move(block.mScalars)),
+      mColIndices(::std::move(block.mColIndices)),
+      mScalars(::std::move(block.mScalars)),
       mPreviousBlock(block.mPreviousBlock),
       mHasNoRows(block.mHasNoRows) 
     {
@@ -405,15 +410,15 @@ private:
     }
 
     void swap(Block& block) {
-      std::swap(mColIndices, block.mColIndices);
-      std::swap(mScalars, block.mScalars);
-      std::swap(mPreviousBlock, block.mPreviousBlock);
-      std::swap(mHasNoRows, block.mHasNoRows);
+      ::std::swap(mColIndices, block.mColIndices);
+      ::std::swap(mScalars, block.mScalars);
+      ::std::swap(mPreviousBlock, block.mPreviousBlock);
+      ::std::swap(mHasNoRows, block.mHasNoRows);
     }
 
     Block& operator=(Block&& block) {
       this->~Block();
-      new (this) Block(std::move(block));
+      new (this) Block(::std::move(block));
       return *this;
     }
 
@@ -436,7 +441,7 @@ private:
 
 template<class T>
 void SparseMatrix::appendRow(
-  std::vector<T> const& v,
+  ::std::vector<T> const& v,
   const ColIndex leadCol
 ) {
 #ifdef MATHICGB_DEBUG
@@ -447,7 +452,7 @@ void SparseMatrix::appendRow(
 
   const auto count = static_cast<ColIndex>(v.size());
   for (ColIndex col = leadCol; col < count; ++col) {
-	MATHICGB_ASSERT(v[col] < std::numeric_limits<Scalar>::max());
+	MATHICGB_ASSERT(v[col] < ::std::numeric_limits<Scalar>::max());
     if (v[col] != 0)
       appendEntry(col, static_cast<Scalar>(v[col]));
   }
@@ -459,6 +464,7 @@ inline void swap(SparseMatrix& a, SparseMatrix& b) {
   a.swap(b);
 }
 
-std::ostream& operator<<(std::ostream& out, const SparseMatrix& matrix);
+::std::ostream& operator<<(::std::ostream& out, const SparseMatrix& matrix);
 
+MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/TournamentReducer.cpp b/src/mathicgb/TournamentReducer.cpp
index 745063e..2add261 100755
--- a/src/mathicgb/TournamentReducer.cpp
+++ b/src/mathicgb/TournamentReducer.cpp
@@ -1,10 +1,12 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
 #include "TournamentReducer.hpp"
 
 #include <utility>
 
+MATHICGB_NAMESPACE_BEGIN
+
 TournamentReducer::TournamentReducer(const PolyRing& ring):
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
@@ -176,8 +178,4 @@ void TournamentReducer::dump() const
 {
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
-
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/TournamentReducer.hpp b/src/mathicgb/TournamentReducer.hpp
index 5879517..b8de07c 100755
--- a/src/mathicgb/TournamentReducer.hpp
+++ b/src/mathicgb/TournamentReducer.hpp
@@ -1,12 +1,14 @@
-// Copyright 2011 Bjarke Roune, Michael E. Stillman
-
-#ifndef _tournament_reducer_h_
-#define _tournament_reducer_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_TOURNAMENT_REDUCER_GUARD
+#define MATHICGB_TOURNAMENT_REDUCER_GUARD
 
 #include "TypicalReducer.hpp"
 #include <mathic.h>
 #include <memtailor.h>
 
+MATHICGB_NAMESPACE_BEGIN
+
 class TournamentReducer : public TypicalReducer {
 public:
   TournamentReducer(const PolyRing& R);
@@ -74,9 +76,5 @@ private:
   memt::BufferPool mPool;
 };
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/TypicalReducer.cpp b/src/mathicgb/TypicalReducer.cpp
index e91cb5a..5c3f9df 100755
--- a/src/mathicgb/TypicalReducer.cpp
+++ b/src/mathicgb/TypicalReducer.cpp
@@ -1,228 +1,234 @@
-#include "stdinc.h"
-#include "TypicalReducer.hpp"
-
-#include "SigPolyBasis.hpp"
-#include "PolyBasis.hpp"
-#include <iostream>
-
-size_t TypicalReducer::preferredSetSize() const {
-  return 1;
-}
-
-void TypicalReducer::reset()
-{
-  mArena.freeAllAllocs();
-  resetReducer();
-}
-
-size_t TypicalReducer::getMemoryUse() const {
-  return mArena.getMemoryUse();
-}
-
-Poly* TypicalReducer::regularReduce(
-  const_monomial sig,
-  const_monomial multiple,
-  size_t basisElement,
-  const SigPolyBasis& basis)
-{
-  const PolyRing& ring = basis.ring();
-  ++mSigStats.reductions;
-
-  monomial tproduct = ring.allocMonomial(mArena);
-  monomial u = ring.allocMonomial(mArena);
-  ring.monomialMult(multiple, basis.getLeadMonomial(basisElement), tproduct);
-
-  size_t reducer = basis.regularReducer(sig, tproduct);
-  if (reducer == static_cast<size_t>(-1)) {
-    ++mSigStats.singularReductions;
-    mArena.freeAllAllocs();
-    return 0; // singular reduction: no regular top reduction possible
-  }
-
-  ring.monomialDivide(tproduct, basis.getLeadMonomial(reducer), u);
-
-  coefficient coef;
-  ring.coefficientSet(coef, 1);
-  insertTail(const_term(coef, multiple), &basis.poly(basisElement));
-
-  MATHICGB_ASSERT(ring.coefficientIsOne(basis.getLeadCoefficient(reducer)));
-  ring.coefficientFromInt(coef, -1);
-  insertTail(const_term(coef, u), &basis.poly(reducer));
-  basis.basis().usedAsReducer(reducer);
-
-  Poly* result = new Poly(ring);
-
-  unsigned long long steps = 2; // number of steps in this reduction
-  for (const_term v; leadTerm(v);) {
-    MATHICGB_ASSERT(v.coeff != 0);
-    reducer = basis.regularReducer(sig, v.monom);
-    if (reducer == static_cast<size_t>(-1)) { // no reducer found
-      result->appendTerm(v.coeff, v.monom);
-      removeLeadTerm();
-    } else { // reduce by reducer
-      ++steps;
-      basis.basis().usedAsReducer(reducer);
-      monomial mon = ring.allocMonomial(mArena);
-      ring.monomialDivide(v.monom, basis.getLeadMonomial(reducer), mon);
-      ring.coefficientDivide(v.coeff, basis.getLeadCoefficient(reducer), coef);
-      ring.coefficientNegateTo(coef);
-      removeLeadTerm();
-      insertTail(const_term(coef, mon), &basis.poly(reducer));
-    }
-  }
-  result->makeMonic();
-
-  mSigStats.steps += steps;
-  mSigStats.maxSteps = std::max(mSigStats.maxSteps, steps);
-  if (result->isZero())
-    ++mSigStats.zeroReductions;
-
-  reset();
-  return result;
-}
-
-std::unique_ptr<Poly> TypicalReducer::classicReduce(const Poly& poly, const PolyBasis& basis) {
-  monomial identity = basis.ring().allocMonomial(mArena);
-  basis.ring().monomialSetIdentity(identity);
-  insert(identity, &poly);
-
-  return classicReduce(basis);
-}
-
-std::unique_ptr<Poly> TypicalReducer::classicTailReduce(const Poly& poly, const PolyBasis& basis) {
-  MATHICGB_ASSERT(&poly.ring() == &basis.ring());
-  MATHICGB_ASSERT(!poly.isZero());
-  term identity;
-  identity.monom = basis.ring().allocMonomial(mArena);
-  basis.ring().monomialSetIdentity(identity.monom);
-  basis.ring().coefficientSetOne(identity.coeff);
-  insertTail(identity, &poly);
-
-  std::unique_ptr<Poly> result(new Poly(basis.ring()));
-  result->appendTerm(poly.getLeadCoefficient(), poly.getLeadMonomial());
-
-  return classicReduce(std::move(result), basis);
-}
-
-std::unique_ptr<Poly> TypicalReducer::classicReduceSPoly(
-  const Poly& a,
-  const Poly& b,
-  const PolyBasis& basis
-) {
-  const PolyRing& ring = basis.ring();
-
-  monomial lcm = ring.allocMonomial();
-  ring.monomialLeastCommonMultiple
-    (a.getLeadMonomial(), b.getLeadMonomial(), lcm);
-
-  // insert tail of multiple of a
-  monomial multiple1 = ring.allocMonomial();
-  ring.monomialDivide(lcm, a.getLeadMonomial(), multiple1);
-  coefficient plusOne;
-  ring.coefficientSet(plusOne, 1);
-  insertTail(const_term(plusOne, multiple1), &a);
-
-  // insert tail of multiple of b
-  monomial multiple2 = ring.allocMonomial();
-  ring.monomialDivide(lcm, b.getLeadMonomial(), multiple2);
-  coefficient minusOne = plusOne;
-  ring.coefficientNegateTo(minusOne);
-  insertTail(const_term(minusOne, multiple2), &b);
-
-  std::unique_ptr<Poly> reduced = classicReduce(basis);
-  ring.freeMonomial(lcm);
-  ring.freeMonomial(multiple1);
-  ring.freeMonomial(multiple2);
-  return std::move(reduced);
-}
-
-void TypicalReducer::classicReduceSPolySet
-(std::vector<std::pair<size_t, size_t> >& spairs,
- const PolyBasis& basis,
- std::vector<std::unique_ptr<Poly> >& reducedOut) {
-  for (auto it = spairs.begin(); it != spairs.end(); ++it) {
-    auto reducedSPoly =
-      classicReduceSPoly(basis.poly(it->first), basis.poly(it->second), basis);
-    if (!reducedSPoly->isZero())
-      reducedOut.push_back(std::move(reducedSPoly));
-  }
-}
-
-void TypicalReducer::classicReducePolySet
-(const std::vector<std::unique_ptr<Poly> >& polys,
- const PolyBasis& basis,
- std::vector<std::unique_ptr<Poly> >& reducedOut)
-{
-  for (auto it = polys.begin(); it != polys.end(); ++it) {
-    auto reducedPoly = classicReduce(**it, basis);
-    if (!reducedPoly->isZero())
-      reducedOut.push_back(std::move(reducedPoly));
-  }  
-}
-
-void TypicalReducer::setMemoryQuantum(size_t quantum) {
-}
-
-std::unique_ptr<Poly> TypicalReducer::classicReduce
-    (std::unique_ptr<Poly> result, const PolyBasis& basis) {
-  const PolyRing& ring = basis.ring();
-  MATHICGB_ASSERT(&result->ring() == &ring);
-  ++mClassicStats.reductions;
-
-  if (tracingLevel > 100)
-    std::cerr << "Classic reduction begun." << std::endl;
-
-  coefficient coef;
-  unsigned long long steps = 0; // number of steps in this reduction
-  for (const_term v; leadTerm(v);) {
-    if (tracingLevel > 100) {
-      std::cerr << "from reducer queue: ";
-      basis.ring().monomialDisplay(std::cerr, v.monom);
-      std::cerr << std::endl;
-    }
-
-    size_t reducer = basis.classicReducer(v.monom);
-    if (reducer == static_cast<size_t>(-1)) { // no reducer found
-      MATHICGB_ASSERT(
-        result->isZero() ||
-        basis.monoid().lessThan(v.monom, result->backMonomial())
-      );
-      result->appendTerm(v.coeff, v.monom);
-      removeLeadTerm();
-    } else { // reduce by reducer
-      ++steps;
-      basis.usedAsReducer(reducer);
-      monomial mon = ring.allocMonomial(mArena);
-      ring.monomialDivide(v.monom, basis.leadMonomial(reducer), mon);
-      ring.coefficientDivide(v.coeff, basis.leadCoefficient(reducer), coef);
-      ring.coefficientNegateTo(coef);
-      removeLeadTerm();
-      insertTail(const_term(coef, mon), &basis.poly(reducer));
-
-      if (tracingLevel > 100) {
-        std::cerr << "Reducing by basis element " << reducer << ": ";
-        basis.poly(reducer).display(std::cerr);
-        std::cerr << std::endl;
-        std::cerr << "multiplied by: " << coef << "  *  ";
-        basis.ring().monomialDisplay(std::cerr, mon);
-        std::cerr << std::endl;
-      }
-    }
-  }
-  result->makeMonic();
-
-  mClassicStats.steps += steps;
-  mClassicStats.maxSteps = std::max(mClassicStats.maxSteps, steps);
-  if (result->isZero())
-    ++mClassicStats.zeroReductions;
-
-  if (tracingLevel > 100)
-    std::cerr << "Classic reduction done." << std::endl;
-
-  reset();
-  return std::move(result);
-}
-
-std::unique_ptr<Poly> TypicalReducer::classicReduce(const PolyBasis& basis) {
-  return classicReduce(make_unique<Poly>(basis.ring()), basis);
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "stdinc.h"
+#include "TypicalReducer.hpp"
+
+#include "SigPolyBasis.hpp"
+#include "PolyBasis.hpp"
+#include <iostream>
+
+MATHICGB_NAMESPACE_BEGIN
+
+size_t TypicalReducer::preferredSetSize() const {
+  return 1;
+}
+
+void TypicalReducer::reset()
+{
+  mArena.freeAllAllocs();
+  resetReducer();
+}
+
+size_t TypicalReducer::getMemoryUse() const {
+  return mArena.getMemoryUse();
+}
+
+Poly* TypicalReducer::regularReduce(
+  const_monomial sig,
+  const_monomial multiple,
+  size_t basisElement,
+  const SigPolyBasis& basis)
+{
+  const PolyRing& ring = basis.ring();
+  ++mSigStats.reductions;
+
+  monomial tproduct = ring.allocMonomial(mArena);
+  monomial u = ring.allocMonomial(mArena);
+  ring.monomialMult(multiple, basis.getLeadMonomial(basisElement), tproduct);
+
+  size_t reducer = basis.regularReducer(sig, tproduct);
+  if (reducer == static_cast<size_t>(-1)) {
+    ++mSigStats.singularReductions;
+    mArena.freeAllAllocs();
+    return 0; // singular reduction: no regular top reduction possible
+  }
+
+  ring.monomialDivide(tproduct, basis.getLeadMonomial(reducer), u);
+
+  coefficient coef;
+  ring.coefficientSet(coef, 1);
+  insertTail(const_term(coef, multiple), &basis.poly(basisElement));
+
+  MATHICGB_ASSERT(ring.coefficientIsOne(basis.getLeadCoefficient(reducer)));
+  ring.coefficientFromInt(coef, -1);
+  insertTail(const_term(coef, u), &basis.poly(reducer));
+  basis.basis().usedAsReducer(reducer);
+
+  Poly* result = new Poly(ring);
+
+  unsigned long long steps = 2; // number of steps in this reduction
+  for (const_term v; leadTerm(v);) {
+    MATHICGB_ASSERT(v.coeff != 0);
+    reducer = basis.regularReducer(sig, v.monom);
+    if (reducer == static_cast<size_t>(-1)) { // no reducer found
+      result->appendTerm(v.coeff, v.monom);
+      removeLeadTerm();
+    } else { // reduce by reducer
+      ++steps;
+      basis.basis().usedAsReducer(reducer);
+      monomial mon = ring.allocMonomial(mArena);
+      ring.monomialDivide(v.monom, basis.getLeadMonomial(reducer), mon);
+      ring.coefficientDivide(v.coeff, basis.getLeadCoefficient(reducer), coef);
+      ring.coefficientNegateTo(coef);
+      removeLeadTerm();
+      insertTail(const_term(coef, mon), &basis.poly(reducer));
+    }
+  }
+  result->makeMonic();
+
+  mSigStats.steps += steps;
+  mSigStats.maxSteps = std::max(mSigStats.maxSteps, steps);
+  if (result->isZero())
+    ++mSigStats.zeroReductions;
+
+  reset();
+  return result;
+}
+
+std::unique_ptr<Poly> TypicalReducer::classicReduce(const Poly& poly, const PolyBasis& basis) {
+  monomial identity = basis.ring().allocMonomial(mArena);
+  basis.ring().monomialSetIdentity(identity);
+  insert(identity, &poly);
+
+  return classicReduce(basis);
+}
+
+std::unique_ptr<Poly> TypicalReducer::classicTailReduce(const Poly& poly, const PolyBasis& basis) {
+  MATHICGB_ASSERT(&poly.ring() == &basis.ring());
+  MATHICGB_ASSERT(!poly.isZero());
+  term identity;
+  identity.monom = basis.ring().allocMonomial(mArena);
+  basis.ring().monomialSetIdentity(identity.monom);
+  basis.ring().coefficientSetOne(identity.coeff);
+  insertTail(identity, &poly);
+
+  std::unique_ptr<Poly> result(new Poly(basis.ring()));
+  result->appendTerm(poly.getLeadCoefficient(), poly.getLeadMonomial());
+
+  return classicReduce(std::move(result), basis);
+}
+
+std::unique_ptr<Poly> TypicalReducer::classicReduceSPoly(
+  const Poly& a,
+  const Poly& b,
+  const PolyBasis& basis
+) {
+  const PolyRing& ring = basis.ring();
+
+  monomial lcm = ring.allocMonomial();
+  ring.monomialLeastCommonMultiple
+    (a.getLeadMonomial(), b.getLeadMonomial(), lcm);
+
+  // insert tail of multiple of a
+  monomial multiple1 = ring.allocMonomial();
+  ring.monomialDivide(lcm, a.getLeadMonomial(), multiple1);
+  coefficient plusOne;
+  ring.coefficientSet(plusOne, 1);
+  insertTail(const_term(plusOne, multiple1), &a);
+
+  // insert tail of multiple of b
+  monomial multiple2 = ring.allocMonomial();
+  ring.monomialDivide(lcm, b.getLeadMonomial(), multiple2);
+  coefficient minusOne = plusOne;
+  ring.coefficientNegateTo(minusOne);
+  insertTail(const_term(minusOne, multiple2), &b);
+
+  std::unique_ptr<Poly> reduced = classicReduce(basis);
+  ring.freeMonomial(lcm);
+  ring.freeMonomial(multiple1);
+  ring.freeMonomial(multiple2);
+  return std::move(reduced);
+}
+
+void TypicalReducer::classicReduceSPolySet
+(std::vector<std::pair<size_t, size_t> >& spairs,
+ const PolyBasis& basis,
+ std::vector<std::unique_ptr<Poly> >& reducedOut) {
+  for (auto it = spairs.begin(); it != spairs.end(); ++it) {
+    auto reducedSPoly =
+      classicReduceSPoly(basis.poly(it->first), basis.poly(it->second), basis);
+    if (!reducedSPoly->isZero())
+      reducedOut.push_back(std::move(reducedSPoly));
+  }
+}
+
+void TypicalReducer::classicReducePolySet
+(const std::vector<std::unique_ptr<Poly> >& polys,
+ const PolyBasis& basis,
+ std::vector<std::unique_ptr<Poly> >& reducedOut)
+{
+  for (auto it = polys.begin(); it != polys.end(); ++it) {
+    auto reducedPoly = classicReduce(**it, basis);
+    if (!reducedPoly->isZero())
+      reducedOut.push_back(std::move(reducedPoly));
+  }  
+}
+
+void TypicalReducer::setMemoryQuantum(size_t quantum) {
+}
+
+std::unique_ptr<Poly> TypicalReducer::classicReduce
+    (std::unique_ptr<Poly> result, const PolyBasis& basis) {
+  const PolyRing& ring = basis.ring();
+  MATHICGB_ASSERT(&result->ring() == &ring);
+  ++mClassicStats.reductions;
+
+  if (tracingLevel > 100)
+    std::cerr << "Classic reduction begun." << std::endl;
+
+  coefficient coef;
+  unsigned long long steps = 0; // number of steps in this reduction
+  for (const_term v; leadTerm(v);) {
+    if (tracingLevel > 100) {
+      std::cerr << "from reducer queue: ";
+      basis.ring().monomialDisplay(std::cerr, v.monom);
+      std::cerr << std::endl;
+    }
+
+    size_t reducer = basis.classicReducer(v.monom);
+    if (reducer == static_cast<size_t>(-1)) { // no reducer found
+      MATHICGB_ASSERT(
+        result->isZero() ||
+        basis.monoid().lessThan(v.monom, result->backMonomial())
+      );
+      result->appendTerm(v.coeff, v.monom);
+      removeLeadTerm();
+    } else { // reduce by reducer
+      ++steps;
+      basis.usedAsReducer(reducer);
+      monomial mon = ring.allocMonomial(mArena);
+      ring.monomialDivide(v.monom, basis.leadMonomial(reducer), mon);
+      ring.coefficientDivide(v.coeff, basis.leadCoefficient(reducer), coef);
+      ring.coefficientNegateTo(coef);
+      removeLeadTerm();
+      insertTail(const_term(coef, mon), &basis.poly(reducer));
+
+      if (tracingLevel > 100) {
+        std::cerr << "Reducing by basis element " << reducer << ": ";
+        basis.poly(reducer).display(std::cerr);
+        std::cerr << std::endl;
+        std::cerr << "multiplied by: " << coef << "  *  ";
+        basis.ring().monomialDisplay(std::cerr, mon);
+        std::cerr << std::endl;
+      }
+    }
+  }
+  result->makeMonic();
+
+  mClassicStats.steps += steps;
+  mClassicStats.maxSteps = std::max(mClassicStats.maxSteps, steps);
+  if (result->isZero())
+    ++mClassicStats.zeroReductions;
+
+  if (tracingLevel > 100)
+    std::cerr << "Classic reduction done." << std::endl;
+
+  reset();
+  return std::move(result);
+}
+
+std::unique_ptr<Poly> TypicalReducer::classicReduce(const PolyBasis& basis) {
+  return classicReduce(make_unique<Poly>(basis.ring()), basis);
+}
+
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/TypicalReducer.hpp b/src/mathicgb/TypicalReducer.hpp
index ff21705..292cda6 100755
--- a/src/mathicgb/TypicalReducer.hpp
+++ b/src/mathicgb/TypicalReducer.hpp
@@ -1,71 +1,77 @@
-#ifndef MATHICGB_TYPICAL_REDUCER_GUARD
-#define MATHICGB_TYPICAL_REDUCER_GUARD
-
-#include "Reducer.hpp"
-#include "Poly.hpp"
-#include "PolyRing.hpp"
-class SigPolyBasis;
-class PolyBasis;
-
-/** Uses the template method pattern (not C++ templates) to implement
-  reduction with some steps left to sub-classes.
-
-  The template method pattern defines an algorithm that calls several
-  virtual methods. Sub-classes can then redefine those methods to
-  change some parts of the algorithm without recoding the whole
-  thing. The word "template" here has nothing to do with C++
-  templates. See http://en.wikipedia.org/wiki/Template_method_pattern
-*/
-class TypicalReducer : public Reducer {
-public:
-  virtual size_t preferredSetSize() const;
-
-  virtual Poly* regularReduce(
-    const_monomial sig,
-    const_monomial multiple,
-    size_t basisElement,
-    const SigPolyBasis& basis);
-
-  virtual std::unique_ptr<Poly> classicReduce
-  (const Poly& poly, const PolyBasis& basis);
-
-  virtual std::unique_ptr<Poly> classicTailReduce
-  (const Poly& poly, const PolyBasis& basis);
-
-  virtual std::unique_ptr<Poly> classicReduceSPoly
-    (const Poly& a, const Poly& b, const PolyBasis& basis);
-
-  virtual void classicReduceSPolySet
-  (std::vector<std::pair<size_t, size_t> >& spairs,
-   const PolyBasis& basis,
-   std::vector<std::unique_ptr<Poly> >& reducedOut);
-
-  virtual void classicReducePolySet
-  (const std::vector<std::unique_ptr<Poly> >& polys,
-   const PolyBasis& basis,
-   std::vector<std::unique_ptr<Poly> >& reducedOut);
-
-  virtual void setMemoryQuantum(size_t quantum);
-
-protected:
-  // These are the methods that sub-classes define in order to carry
-  // out sub-steps in the reduction.
-  virtual void insertTail(const_term multiplier, const Poly *f) = 0;
-  virtual void insert(monomial multiplier, const Poly *f) = 0;
-  virtual bool leadTerm(const_term& result) = 0;
-  virtual void removeLeadTerm() = 0;
-  virtual void resetReducer() = 0;
-
-  virtual size_t getMemoryUse() const;
-
-  // Sub-classes can use this
-  memt::Arena mArena;
-
-private:
-  void reset();
-  std::unique_ptr<Poly> classicReduce(const PolyBasis& basis);
-  std::unique_ptr<Poly> classicReduce
-    (std::unique_ptr<Poly> partialResult, const PolyBasis& basis);
-};
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_TYPICAL_REDUCER_GUARD
+#define MATHICGB_TYPICAL_REDUCER_GUARD
+
+#include "Reducer.hpp"
+#include "Poly.hpp"
+#include "PolyRing.hpp"
+
+MATHICGB_NAMESPACE_BEGIN
+
+class SigPolyBasis;
+class PolyBasis;
+
+/** Uses the template method pattern (not C++ templates) to implement
+  reduction with some steps left to sub-classes.
+
+  The template method pattern defines an algorithm that calls several
+  virtual methods. Sub-classes can then redefine those methods to
+  change some parts of the algorithm without recoding the whole
+  thing. The word "template" here has nothing to do with C++
+  templates. See http://en.wikipedia.org/wiki/Template_method_pattern
+*/
+class TypicalReducer : public Reducer {
+public:
+  virtual size_t preferredSetSize() const;
+
+  virtual Poly* regularReduce(
+    const_monomial sig,
+    const_monomial multiple,
+    size_t basisElement,
+    const SigPolyBasis& basis);
+
+  virtual std::unique_ptr<Poly> classicReduce
+  (const Poly& poly, const PolyBasis& basis);
+
+  virtual std::unique_ptr<Poly> classicTailReduce
+  (const Poly& poly, const PolyBasis& basis);
+
+  virtual std::unique_ptr<Poly> classicReduceSPoly
+    (const Poly& a, const Poly& b, const PolyBasis& basis);
+
+  virtual void classicReduceSPolySet
+  (std::vector<std::pair<size_t, size_t> >& spairs,
+   const PolyBasis& basis,
+   std::vector<std::unique_ptr<Poly> >& reducedOut);
+
+  virtual void classicReducePolySet
+  (const std::vector<std::unique_ptr<Poly> >& polys,
+   const PolyBasis& basis,
+   std::vector<std::unique_ptr<Poly> >& reducedOut);
+
+  virtual void setMemoryQuantum(size_t quantum);
+
+protected:
+  // These are the methods that sub-classes define in order to carry
+  // out sub-steps in the reduction.
+  virtual void insertTail(const_term multiplier, const Poly *f) = 0;
+  virtual void insert(monomial multiplier, const Poly *f) = 0;
+  virtual bool leadTerm(const_term& result) = 0;
+  virtual void removeLeadTerm() = 0;
+  virtual void resetReducer() = 0;
+
+  virtual size_t getMemoryUse() const;
+
+  // Sub-classes can use this
+  memt::Arena mArena;
+
+private:
+  void reset();
+  std::unique_ptr<Poly> classicReduce(const PolyBasis& basis);
+  std::unique_ptr<Poly> classicReduce
+    (std::unique_ptr<Poly> partialResult, const PolyBasis& basis);
+};
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/Unchar.hpp b/src/mathicgb/Unchar.hpp
index f93e0fc..d560bbf 100755
--- a/src/mathicgb/Unchar.hpp
+++ b/src/mathicgb/Unchar.hpp
@@ -1,39 +1,43 @@
-#ifndef MATHICGB_UNCHAR_GUARD
-#define MATHICGB_UNCHAR_GUARD
-
-#include <type_traits>
-
-/// std::ostream and std::istream handle characters differently from
-/// other integers. That is not desired when using char as an
-/// integer. Use Unchar and unchar() to cast chars to a different type
-/// that get handled as other integers do.
-template<class T>
-struct Unchar {typedef T type;};
-
-// Strange but true: char, signed char and unsigned char are 3
-// distinct types. Also, the signedness of char is unspecified. This
-// is in contrast to all the other built-in types. For example, int
-// and signed int are always the exact same type.
-
-namespace UncharInternal {
-  // Two cases depending on whether char is signed or not.
-  template<bool Signed = std::is_signed<char>::value>
-  struct ExtendedChar {typedef signed short type;};
-  template<>
-  struct ExtendedChar<false> {typedef unsigned short type;};
-    
-};
-
-template<>
-struct Unchar<char> {
-  typedef typename UncharInternal::ExtendedChar<>::type type;
-};
-template<>
-struct Unchar<signed char> {typedef short type;};
-template<>
-struct Unchar<unsigned char> {typedef unsigned short type;};
-
-template<class T>
-typename Unchar<T>::type unchar(const T& t) {return t;}
-
-#endif
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_UNCHAR_GUARD
+#define MATHICGB_UNCHAR_GUARD
+
+#include <type_traits>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// std::ostream and std::istream handle characters differently from
+/// other integers. That is not desired when using char as an
+/// integer. Use Unchar and unchar() to cast chars to a different type
+/// that get handled as other integers do.
+template<class T>
+struct Unchar {typedef T type;};
+
+// Strange but true: char, signed char and unsigned char are 3
+// distinct types. Also, the signedness of char is unspecified. This
+// is in contrast to all the other built-in types. For example, int
+// and signed int are always the exact same type.
+
+namespace UncharInternal {
+  // Two cases depending on whether char is signed or not.
+  template<bool Signed = std::is_signed<char>::value>
+  struct ExtendedChar {typedef signed short type;};
+  template<>
+  struct ExtendedChar<false> {typedef unsigned short type;};    
+};
+
+template<>
+struct Unchar<char> {
+  typedef typename UncharInternal::ExtendedChar<>::type type;
+};
+template<>
+struct Unchar<signed char> {typedef short type;};
+template<>
+struct Unchar<unsigned char> {typedef unsigned short type;};
+
+template<class T>
+typename Unchar<T>::type unchar(const T& t) {return t;}
+
+MATHICGB_NAMESPACE_END
+#endif
diff --git a/src/mathicgb/io-util.cpp b/src/mathicgb/io-util.cpp
index 87248e6..cb3d77e 100755
--- a/src/mathicgb/io-util.cpp
+++ b/src/mathicgb/io-util.cpp
@@ -1,133 +1,135 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "stdinc.h"
-#include <cstdio>
-#include <string>
-#include <iostream>
-#include <sstream>
+#include "io-util.hpp"
+
 #include "Poly.hpp"
 #include "MTArray.hpp"
 #include "io-util.hpp"
 #include "Scanner.hpp"
 #include "MathicIO.hpp"
-
 #include "PolyHeap.hpp"
 #include "PolyGeoBucket.hpp"
 #include "SigPolyBasis.hpp"
 #include "SignatureGB.hpp"
 #include "MTArray.hpp"
-
 #include "Basis.hpp"
 #include "PolyBasis.hpp"
+#include <cstdio>
+#include <string>
+#include <iostream>
+#include <sstream>
+
+MATHICGB_NAMESPACE_BEGIN
 
-std::unique_ptr<Poly> polyParseFromString(const PolyRing *R, const std::string &s)
+::std::unique_ptr<Poly> polyParseFromString(const PolyRing *R, const ::std::string &s)
 {
-  std::unique_ptr<Poly> f(new Poly(*R));
-  std::istringstream in(s);
+  ::std::unique_ptr<Poly> f(new Poly(*R));
+  ::std::istringstream in(s);
   f->parse(in);
   return f;
 }
 
-std::string toString(const Poly *g)
+::std::string toString(const Poly *g)
 {
-  std::ostringstream o;
+  ::std::ostringstream o;
   g->display(o);
   return o.str();
 }
 
-std::unique_ptr<Basis> basisParseFromString(std::string str)
+::std::unique_ptr<Basis> basisParseFromString(::std::string str)
 {
-  std::istringstream inStream(str);
+  ::std::istringstream inStream(str);
   Scanner in(inStream);
   auto p = MathicIO().readRing(true, in);
   auto& ring = *p.first.release(); // todo: fix leak
   return make_unique<Basis>(MathicIO().readBasis(ring, false, in));
 }
 
-std::unique_ptr<PolyRing> ringFromString(std::string ringinfo)
+::std::unique_ptr<PolyRing> ringFromString(::std::string ringinfo)
 {
-  std::stringstream ifil(ringinfo);
-  return std::unique_ptr<PolyRing>(PolyRing::read(ifil).first);
+  ::std::stringstream ifil(ringinfo);
+  return ::std::unique_ptr<PolyRing>(PolyRing::read(ifil).first);
 }
 
-Monomial stringToMonomial(const PolyRing *R, std::string mon)
+Monomial stringToMonomial(const PolyRing *R, ::std::string mon)
 {
   Monomial result = R->allocMonomial();
-  std::stringstream ifil(mon);
+  ::std::stringstream ifil(mon);
   R->monomialParse(ifil, result);
   return result;
 }
 
-std::string monomialToString(const PolyRing *R, const Monomial& mon)
+::std::string monomialToString(const PolyRing *R, const Monomial& mon)
 {
-  std::ostringstream o;
+  ::std::ostringstream o;
   R->monomialDisplay(o,mon);
   return o.str();
 }
 
-monomial monomialParseFromString(const PolyRing *R, std::string mon)
+monomial monomialParseFromString(const PolyRing *R, ::std::string mon)
 {
   // This is poor code, to only be used for testing!
   monomial result = R->allocMonomial();
-  std::stringstream ifil(mon);
+  ::std::stringstream ifil(mon);
   R->monomialParse(ifil, result);
   return result;
 }
 
-std::string monomialDisplay(const PolyRing *R, const_monomial mon)
+::std::string monomialDisplay(const PolyRing *R, const_monomial mon)
 {
-  std::ostringstream o;
+  ::std::ostringstream o;
   R->monomialDisplay(o,mon);
   return o.str();
 }
 ////////////////////////////////////////////////////////////////
 
-std::string toString(SigPolyBasis *I)
+::std::string toString(SigPolyBasis *I)
 {
-  std::ostringstream o;
+  ::std::ostringstream o;
   for (size_t i=0; i<I->size(); i++)
     {
       o << "  ";
       I->poly(i).display(o, false);
-      o << std::endl;
+      o << ::std::endl;
     }
   return o.str();
 }
 
-std::string toString(SigPolyBasis *I, int)
+::std::string toString(SigPolyBasis *I, int)
 {
-  std::ostringstream o;
+  ::std::ostringstream o;
   I->display(o);
   return o.str();
 }
 
-std::string toString(MonomialTableArray* H)
+::std::string toString(MonomialTableArray* H)
 {
-  std::ostringstream o;
+  ::std::ostringstream o;
   H->display(o, 1);
   return o.str();
 }
 
-std::string toString(Basis *I)
+::std::string toString(Basis *I)
 {
-  std::ostringstream o;
+  ::std::ostringstream o;
   for (size_t i=0; i<I->size(); i++)
     {
       o << "  ";
       I->getPoly(i)->display(o,false);
-      o << std::endl;
+      o << ::std::endl;
     }
   return o.str();
 }
 
-void output(std::ostream &o, const PolyBasis &I)
+void output(::std::ostream &o, const PolyBasis &I)
 {
   for (size_t i = 0; i < I.size(); i++)
     {
       if (!I.retired(i))
         {
           I.poly(i).display(o, false);
-          o << std::endl;
+          o << ::std::endl;
         }
     }
 }
@@ -144,7 +146,4 @@ void output(FILE* file, const PolyBasis &I)
     }
 }
 
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/io-util.hpp b/src/mathicgb/io-util.hpp
index 80926de..7d62859 100755
--- a/src/mathicgb/io-util.hpp
+++ b/src/mathicgb/io-util.hpp
@@ -1,40 +1,39 @@
-// Copyright 2011 Michael E. Stillman
-
-#ifndef _io_util_h_
-#define _io_util_h_
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_IO_UTIL_GUARD
+#define MATHICGB_IO_UTIL_GUARD
 
 #include "PolyRing.hpp"
 
+MATHICGB_NAMESPACE_BEGIN
+
 class Poly;
 class SigPolyBasis;
 class MonomialTableArray;
 class PolyBasis;
 class Basis;
 
-std::unique_ptr<PolyRing> ringFromString(std::string ringinfo);
-monomial monomialFromString(const PolyRing *R, std::string mon);
-monomial monomialParseFromString(const PolyRing *R, std::string mon);
-std::string monomialToString(const PolyRing *R, const_monomial mon);
-std::string monomialDisplay(const PolyRing *R, const_monomial mon);
+::std::unique_ptr<PolyRing> ringFromString(::std::string ringinfo);
+monomial monomialFromString(const PolyRing *R, ::std::string mon);
+monomial monomialParseFromString(const PolyRing *R, ::std::string mon);
+::std::string monomialToString(const PolyRing *R, const_monomial mon);
+::std::string monomialDisplay(const PolyRing *R, const_monomial mon);
 
-Monomial stringToMonomial(const PolyRing *R, std::string mon);
-std::string monomialToString(const PolyRing *R, const Monomial& mon);
+Monomial stringToMonomial(const PolyRing *R, ::std::string mon);
+::std::string monomialToString(const PolyRing *R, const Monomial& mon);
 
-std::string toString(SigPolyBasis *);
-std::string toString(MonomialTableArray *);
-std::string toString(SigPolyBasis *, int unused); // also displays signature
-std::string toString(Basis *);
-std::string toString(const Poly *);
+::std::string toString(SigPolyBasis *);
+::std::string toString(MonomialTableArray *);
+::std::string toString(SigPolyBasis *, int unused); // also displays signature
+::std::string toString(Basis *);
+::std::string toString(const Poly *);
 
-std::unique_ptr<Basis> basisParseFromString(std::string str);
-std::unique_ptr<Poly> polyParseFromString(const PolyRing *R, const std::string &s);
+::std::unique_ptr<Basis> basisParseFromString(::std::string str);
+::std::unique_ptr<Poly> polyParseFromString
+  (const PolyRing *R, const ::std::string &s);
 
-void output(std::ostream &o, const PolyBasis &I);
+void output(::std::ostream &o, const PolyBasis &I);
 void output(FILE* file, const PolyBasis &I);
 
+MATHICGB_NAMESPACE_END
 #endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/mtbb.hpp b/src/mathicgb/mtbb.hpp
index e0e313b..5898260 100755
--- a/src/mathicgb/mtbb.hpp
+++ b/src/mathicgb/mtbb.hpp
@@ -1,237 +1,243 @@
-#ifndef MATHICGB_TBB_GUARD
-#define MATHICGB_TBB_GUARD
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_M_TBB_GUARD
+#define MATHICGB_M_TBB_GUARD
 
 #ifndef MATHICGB_NO_TBB
 #include <tbb/tbb.h>
 
-namespace mgb {
-  namespace tbb {
-    using ::tbb::task_scheduler_init;
-    using ::tbb::mutex;
-    using ::tbb::parallel_do_feeder;
-    using ::tbb::enumerable_thread_specific;
-    using ::tbb::parallel_do;
-    using ::tbb::parallel_for;
-    using ::tbb::parallel_sort;
-    using ::tbb::blocked_range;
-    using ::tbb::tick_count;
-  }
+MATHICGB_NAMESPACE_BEGIN
+
+namespace tbb {
+  using ::tbb::task_scheduler_init;
+  using ::tbb::mutex;
+  using ::tbb::parallel_do_feeder;
+  using ::tbb::enumerable_thread_specific;
+  using ::tbb::parallel_do;
+  using ::tbb::parallel_for;
+  using ::tbb::parallel_sort;
+  using ::tbb::blocked_range;
+  using ::tbb::tick_count;
 }
 
+MATHICGB_NAMESPACE_END
 #else
+
 #include <functional>
 #include <vector>
 #include <ctime>
 #include <algorithm>
 #include <chrono>
 
-namespace mgb {
-  namespace tbb {
-    class task_scheduler_init {
-    public:
-      task_scheduler_init(int) {}
-      static const int automatic = 1;
-    };
+MATHICGB_NAMESPACE_BEGIN
 
-    class mutex {
+namespace tbb {
+  class task_scheduler_init {
+  public:
+    task_scheduler_init(int) {}
+    static const int automatic = 1;
+  };
+
+  class mutex {
+  public:
+    mutex(): mLocked(false) {}
+
+    class scoped_lock {
     public:
-      mutex(): mLocked(false) {}
-
-      class scoped_lock {
-      public:
-        scoped_lock(): mMutex(0) {}
-        scoped_lock(mutex& m): mMutex(&m) {mMutex->lock();}
-        ~scoped_lock() {
-          if (mMutex != 0)
-            release();
-        }
-
-        void acquire(mutex& m) {
-          MATHICGB_ASSERT(mMutex == 0);
-          mMutex = &m;
-        }
-
-        bool try_acquire(mutex& m) {
-          MATHICGB_ASSERT(mMutex == 0);
-          if (!m.try_lock())
-            return false;
-          mMutex = &m;
-          return true;
-        }
-
-        void release() {
-          MATHICGB_ASSERT(mMutex != 0);
-          mMutex->unlock();
-          mMutex = 0;
-        }
-
-      private:
-        mutex* mMutex;
-      };
-
-      void lock() {
-        MATHICGB_ASSERT(!mLocked); // deadlock
-        mLocked = true;
+      scoped_lock(): mMutex(0) {}
+      scoped_lock(mutex& m): mMutex(&m) {mMutex->lock();}
+      ~scoped_lock() {
+        if (mMutex != 0)
+          release();
       }
 
-      bool try_lock() {
-        if (mLocked)
+      void acquire(mutex& m) {
+        MATHICGB_ASSERT(mMutex == 0);
+        mMutex = &m;
+      }
+
+      bool try_acquire(mutex& m) {
+        MATHICGB_ASSERT(mMutex == 0);
+        if (!m.try_lock())
           return false;
-        lock();
+        mMutex = &m;
         return true;
       }
 
-      void unlock() {
-        MATHICGB_ASSERT(mLocked);
-        mLocked = false;
+      void release() {
+        MATHICGB_ASSERT(mMutex != 0);
+        mMutex->unlock();
+        mMutex = 0;
       }
 
     private:
-      bool mLocked;
+      mutex* mMutex;
     };
 
-    template<class T>
-    class enumerable_thread_specific {
-    public:
-      template<class Op>
-      enumerable_thread_specific(Op&& creater): mCreater(creater) {}
-
-      bool empty() const {return mObj.get() == 0;}
-
-      T& local() {
-        if (empty())
-          mObj = make_unique<T>(mCreater());
-        MATHICGB_ASSERT(!empty());
-        return *mObj;
-      }
-
-      T* begin() {
-        if (empty())
-          return 0;
-        else
-          return mObj.get();
-      }
-
-      T* end() {
-        if (empty())
-          return  0;
-        else
-          return begin() + 1;
-      }
+    void lock() {
+      MATHICGB_ASSERT(!mLocked); // deadlock
+      mLocked = true;
+    }
 
-      void clear() {
-        mObj.reset(0);
-      }
+    bool try_lock() {
+      if (mLocked)
+        return false;
+      lock();
+      return true;
+    }
 
-    private:
-      std::function<T()> mCreater;
-      std::unique_ptr<T> mObj;
-    };
+    void unlock() {
+      MATHICGB_ASSERT(mLocked);
+      mLocked = false;
+    }
 
-    template<class Value>
-    class blocked_range {
-    public:
-      typedef size_t size_type;
-      typedef Value const_iterator;
+  private:
+    bool mLocked;
+  };
 
-      blocked_range(Value begin, Value end, size_t grainSize = 1):
-        mBegin(begin), mEnd(end), mGrainSize(grainSize) {}
+  template<class T>
+  class enumerable_thread_specific {
+  public:
+    template<class Op>
+    enumerable_thread_specific(Op&& creater): mCreater(creater) {}
 
-      size_type size() const {return end() - begin();}
-      bool empty() const {return mBegin == mEnd;}
-      size_type grainsize() const {return mGrainSize;}
-      bool is_divisible() const {return false;}
+    bool empty() const {return mObj.get() == 0;}
 
-      const_iterator begin() const {return mBegin;}
-      const_iterator end() const {return mEnd;}
+    T& local() {
+      if (empty())
+        mObj = make_unique<T>(mCreater());
+      MATHICGB_ASSERT(!empty());
+      return *mObj;
+    }
 
-    private:
-      const_iterator mBegin;
-      const_iterator mEnd;
-      size_type mGrainSize;
-    };
-    
-    template<class Range, class Func>
-    void parallel_for(Range&& range, Func&& f) {
-      f(range);
+    T* begin() {
+      if (empty())
+        return 0;
+      else
+        return mObj.get();
     }
 
-    template<class Index, class Func>
-    void parallel_for(Index begin, Index end, Index step, Func&& f) {
-      for (auto i = begin; i < end; i += step)
-        f(i);
+    T* end() {
+      if (empty())
+        return  0;
+      else
+        return begin() + 1;
     }
 
-    template<class T>
-    class parallel_do_feeder {
-    public:
-      parallel_do_feeder(std::vector<T>& tasks): mTasks(tasks) {}
+    void clear() {
+      mObj.reset(0);
+    }
 
-      template<class TT>
-      void add(TT&& t) {mTasks.push_back(std::forward<TT>(t));}
+  private:
+    ::std::function<T()> mCreater;
+    ::std::unique_ptr<T> mObj;
+  };
+
+  template<class Value>
+  class blocked_range {
+  public:
+    typedef size_t size_type;
+    typedef Value const_iterator;
+
+    blocked_range(Value begin, Value end, size_t grainSize = 1):
+      mBegin(begin), mEnd(end), mGrainSize(grainSize) {}
+
+    size_type size() const {return end() - begin();}
+    bool empty() const {return mBegin == mEnd;}
+    size_type grainsize() const {return mGrainSize;}
+    bool is_divisible() const {return false;}
+
+    const_iterator begin() const {return mBegin;}
+    const_iterator end() const {return mEnd;}
+
+  private:
+    const_iterator mBegin;
+    const_iterator mEnd;
+    size_type mGrainSize;
+  };
+    
+  template<class Range, class Func>
+  void parallel_for(Range&& range, Func&& f) {
+    f(range);
+  }
 
-    private:
-      std::vector<T>& mTasks;
-    };
+  template<class Index, class Func>
+  void parallel_for(Index begin, Index end, Index step, Func&& f) {
+    for (auto i = begin; i < end; i += step)
+      f(i);
+  }
 
-    template<class InputIterator, class Body>
-    void parallel_do(InputIterator begin, InputIterator end, Body body) {
-      typedef typename std::remove_reference<decltype(*begin)>::type Task;
-      std::vector<Task> tasks;
-      parallel_do_feeder<Task> feeder(tasks);
-      for (; begin != end; ++begin) {
-        tasks.push_back(*begin);
-        while (!tasks.empty()) {
-          auto task = std::move(tasks.back());
-          tasks.pop_back();
-          body(task, feeder);
-        }
+  template<class T>
+  class parallel_do_feeder {
+  public:
+    parallel_do_feeder(::std::vector<T>& tasks): mTasks(tasks) {}
+
+    template<class TT>
+    void add(TT&& t) {mTasks.push_back(::std::forward<TT>(t));}
+
+  private:
+    ::std::vector<T>& mTasks;
+  };
+
+  template<class InputIterator, class Body>
+  void parallel_do(InputIterator begin, InputIterator end, Body body) {
+    typedef typename ::std::remove_reference<decltype(*begin)>::type Task;
+    ::std::vector<Task> tasks;
+    parallel_do_feeder<Task> feeder(tasks);
+    for (; begin != end; ++begin) {
+      tasks.push_back(*begin);
+      while (!tasks.empty()) {
+        auto task = ::std::move(tasks.back());
+        tasks.pop_back();
+        body(task, feeder);
       }
     }
+  }
 
-    template<class It, class Pred>
-    void parallel_sort(It begin, It end, Pred&& pred) {
-      std::sort(begin, end, pred);
-    }
-
-    class tick_count {
-    private:
-      // This really should be std::chrono::steady_clock, but GCC 4.5.3 doesn't
-      // have that.
-      typedef std::chrono::system_clock clock;
-
-    public:
-      tick_count(): mTime() {}
+  template<class It, class Pred>
+  void parallel_sort(It begin, It end, Pred&& pred) {
+    ::std::sort(begin, end, pred);
+  }
 
-      static tick_count now() {
-        tick_count t;
-        t.mTime = clock::now();
-        return t;
-      }
+  class tick_count {
+  private:
+    // This really should be ::std::chrono::steady_clock, but GCC 4.5.3 doesn't
+    // have that.
+    typedef ::std::chrono::system_clock clock;
 
-      class interval_t {
-      public:
-        interval_t(double seconds): mSeconds(seconds) {}
+  public:
+    tick_count(): mTime() {}
 
-        double seconds() const {return mSeconds;}
+    static tick_count now() {
+      tick_count t;
+      t.mTime = clock::now();
+      return t;
+    }
 
-      private:
-        const double mSeconds;
-      };
+    class interval_t {
+    public:
+      interval_t(double seconds): mSeconds(seconds) {}
 
-      interval_t operator-(const tick_count t) const {
-        typedef std::chrono::duration<double> SecondDuration;
-        const auto duration =
-          std::chrono::duration_cast<SecondDuration>(mTime - t.mTime);
-        return duration.count();
-      }
+      double seconds() const {return mSeconds;}
 
     private:
-      clock::time_point mTime;
+      const double mSeconds;
     };
-  }
+
+    interval_t operator-(const tick_count t) const {
+      typedef ::std::chrono::duration<double> SecondDuration;
+      const auto duration =
+        ::std::chrono::duration_cast<SecondDuration>(mTime - t.mTime);
+      return duration.count();
+    }
+
+  private:
+    clock::time_point mTime;
+  };
 }
 
+
+MATHICGB_NAMESPACE_END
 #endif
 
 #endif
diff --git a/src/mathicgb/stdinc.h b/src/mathicgb/stdinc.h
index 792ee94..91812ff 100755
--- a/src/mathicgb/stdinc.h
+++ b/src/mathicgb/stdinc.h
@@ -160,6 +160,16 @@
 /// as that macro does.
 #define MATHICGB_CONCATENATE_AFTER_EXPANSION(A,B) MATHICGB_CONCATENATE(A,B)
 
+/// Opens the mgb namespace. The purpose of having this be a macro is
+/// that otherwise editors the world over would automatically indent ALL
+/// CODE in MathicGB by an extra level to no benefit. By hiding the
+/// open and close braces inside a macro, the editors cannot see it so they
+/// do not indent because of it. Also, while transitioning to using
+/// the namespace, this was a useful way to insert the proper code in
+/// each file while still keeping everything compiling mid-way.
+#define MATHICGB_NAMESPACE_BEGIN namespace mgb {
+#define MATHICGB_NAMESPACE_END }
+
 #include <utility>
 /*
 See http://herbsutter.com/gotw/_102/ for a reason to have a
@@ -178,6 +188,8 @@ for N parameters! Add more overloads below if you need more
 parameters.
 */
 
+MATHICGB_NAMESPACE_BEGIN
+
 template<class T>
 std::unique_ptr<T> make_unique() {
   return std::unique_ptr<T>(new T());
@@ -291,3 +303,5 @@ static const size_t MemoryAlignment = sizeof(void*);
 /// The higher the value the more detailed output about what the program
 /// is doing.
 extern int tracingLevel;
+
+MATHICGB_NAMESPACE_END
diff --git a/src/test/F4MatrixBuilder.cpp b/src/test/F4MatrixBuilder.cpp
index 0ac2828..549f7e4 100755
--- a/src/test/F4MatrixBuilder.cpp
+++ b/src/test/F4MatrixBuilder.cpp
@@ -1,178 +1,182 @@
-#include "mathicgb/stdinc.h"
-
-#include "mathicgb/Poly.hpp"
-#include "mathicgb/PolyRing.hpp"
-#include "mathicgb/F4MatrixBuilder.hpp"
-#include "mathicgb/Basis.hpp"
-#include "mathicgb/PolyBasis.hpp"
-#include "mathicgb/io-util.hpp"
-#include "mathicgb/mtbb.hpp"
-
-#include <gtest/gtest.h>
-#include <memory>
-
-namespace {
-  // We need a struct to keep the ring and so on alive after
-  // construction - we cannot just return an object.
-  //
-  // @todo: This whole thing is fairly ridiculous - some kind of more
-  // general dependency injection mechanism might be nice here.
-  struct BuilderMaker {
-    BuilderMaker():
-      mRing(ringFromString("101 6 1\n1 1 1 1 1 1")),
-      mIdeal(*mRing),
-      mBasis(*mRing, DivisorLookup::makeFactory(*mRing, 1)->create(true, true)) {
-    }
-
-    const Poly& addBasisElement(const std::string& str) {
-      std::unique_ptr<Poly> p(new Poly(*mRing));
-      std::istringstream in(str);
-      p->parse(in);
-      mBasis.insert(std::move(p));
-      return mBasis.poly(mBasis.size() - 1);
-    }
-
-    F4MatrixBuilder& create() {
-      MATHICGB_ASSERT(mBuilder.get() == 0);
-      mBuilder.reset(new F4MatrixBuilder(mBasis));
-      return *mBuilder;
-    }
-
-    const PolyRing& ring() const {return *mRing;}
-     
-  private:
-    std::unique_ptr<PolyRing> mRing;
-    Basis mIdeal;
-    PolyBasis mBasis;
-    std::unique_ptr<F4MatrixBuilder> mBuilder;
-  };
-}
-
-TEST(F4MatrixBuilder, Empty) {
-  for (int threadCount = 1; threadCount < 4; ++threadCount) {
-    mgb::tbb::task_scheduler_init scheduler(threadCount);
-    BuilderMaker maker;
-    F4MatrixBuilder& builder = maker.create();
-
-    QuadMatrix matrix;
-    builder.buildMatrixAndClear(matrix);
-    ASSERT_EQ(0, matrix.topLeft.rowCount());
-    ASSERT_EQ(0, matrix.bottomLeft.rowCount());
-    ASSERT_EQ(0, matrix.topLeft.computeColCount());
-    ASSERT_EQ(0, matrix.topRight.computeColCount());
-    ASSERT_EQ(0, matrix.leftColumnMonomials.size());
-    ASSERT_EQ(0, matrix.rightColumnMonomials.size());
-  }
-}
-
-TEST(F4MatrixBuilder, SPair) {
-  for (int threadCount = 1; threadCount < 4; ++threadCount) {
-    mgb::tbb::task_scheduler_init scheduler(threadCount);
-    BuilderMaker maker;
-    const Poly& p1 = maker.addBasisElement("a4c2-d");
-    const Poly& p2 = maker.addBasisElement("a4b+d");
-    // S-pair of p1 and p2 is -c2d-bd
-    const Poly& p3 = maker.addBasisElement("c2d+3");
-    F4MatrixBuilder& builder = maker.create();
-    builder.addSPolynomialToMatrix(p1, p2);
-    QuadMatrix qm;
-    builder.buildMatrixAndClear(qm);
-    const char* const str1 = 
-      "Left columns: c2d\n"
-      "Right columns: bd 1\n"
-      "0: 0#1   | 0: 1#3  \n"
-      "         |         \n"
-      "0: 0#100 | 0: 0#100\n";
-    const char* const str2 = 
-      "Left columns: c2d\n"
-      "Right columns: bd 1\n"
-      "0: 0#1 | 0: 0#1\n"
-      "       |       \n"
-      "0: 0#1 | 0: 1#3\n";
-    std::string qmStr = qm.toString();
-    ASSERT_TRUE(str1 == qmStr || str2 == qmStr) <<
-      "\n** str1: " << str1 << "\n** qm: " << qmStr;
-  }
-}
-
-TEST(F4MatrixBuilder, OneByOne) {
-  for (int threadCount = 1; threadCount < 4; ++threadCount) {
-    mgb::tbb::task_scheduler_init scheduler(threadCount);
-    BuilderMaker maker;
-    const Poly& p = maker.addBasisElement("a");
-    F4MatrixBuilder& builder = maker.create();
-    builder.addPolynomialToMatrix(p.getLeadMonomial(), p);
-    QuadMatrix qm;
-    builder.buildMatrixAndClear(qm);
-    const char* str = 
-      "Left columns: a2\n"
-      "Right columns:\n"
-      "0: 0#1 | 0:\n"
-      "       |   \n"
-      "0: 0#1 | 0:\n";
-    ASSERT_EQ(str, qm.toString()) << "** qm:\n" << qm;
-  }
-}
-
-TEST(F4MatrixBuilder, DirectReducers) {
-  for (int threadCount = 1; threadCount < 4; ++threadCount) {
-    BuilderMaker maker;
-    maker.addBasisElement("a6<0>"); // reducer == to lead term
-    maker.addBasisElement("a3b2<0>+a3c"); // reducer == to lower order term
-    maker.addBasisElement("c<0>"); // reducer divides
-    maker.addBasisElement("d2<0>"); // does not divide
-    F4MatrixBuilder& builder = maker.create();
-
-    Poly p1(builder.ring());
-    { 
-      std::istringstream in("a3<0>+b2+c+d");
-      p1.parse(in);
-      builder.addPolynomialToMatrix(p1.getLeadMonomial(), p1);
-    }
-
-    Poly p2(builder.ring());
-    {
-      std::istringstream in("a3<0>+2b2+3c+4d");
-      p2.parse(in);
-      builder.addPolynomialToMatrix(p2.getLeadMonomial(), p2);
-    }
-
-    QuadMatrix qm;
-    builder.buildMatrixAndClear(qm);
-
-    const char* str =
-      "Left columns: a6 a3b2 a3c\n"
-      "Right columns: a3d\n"
-      "0: 2#1         | 0:    \n"
-      "1: 1#1 2#1     | 1:    \n"
-      "2: 0#1         | 2:    \n"
-      "               |       \n"
-      "0: 0#1 1#1 2#1 | 0: 0#1\n"
-      "1: 0#1 1#2 2#3 | 1: 0#4\n";
-    qm = qm.toCanonical();
-    ASSERT_EQ(str, qm.toString()) << "** qm:\n" << qm;
-  }
-}
-
-TEST(F4MatrixBuilder, IteratedReducer) {
-  for (int threadCount = 1; threadCount < 4; ++threadCount) {
-    BuilderMaker maker;
-    const Poly& p1 = maker.addBasisElement("a4-a3");
-    const Poly& p2 = maker.addBasisElement("a-1");
-    F4MatrixBuilder& builder = maker.create();
-    builder.addPolynomialToMatrix(p1.getLeadMonomial(), p2);
-    QuadMatrix qm;
-    builder.buildMatrixAndClear(qm);
-    const char* str = 
-      "Left columns: a5 a4 a3 a2 a\n"
-      "Right columns: 1\n"
-      "0: 4#1       | 0: 0#100\n"
-      "1: 3#1 4#100 | 1:      \n"
-      "2: 2#1 3#100 | 2:      \n"
-      "3: 1#1 2#100 | 3:      \n"
-      "4: 0#1 1#100 | 4:      \n"
-      "             |         \n"
-      "0: 0#1 1#100 | 0:      \n";
-    ASSERT_EQ(str, qm.toCanonical().toString()) << "** qm:\n" << qm;
-  }
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+
+#include "mathicgb/Poly.hpp"
+#include "mathicgb/PolyRing.hpp"
+#include "mathicgb/F4MatrixBuilder.hpp"
+#include "mathicgb/Basis.hpp"
+#include "mathicgb/PolyBasis.hpp"
+#include "mathicgb/io-util.hpp"
+#include "mathicgb/mtbb.hpp"
+
+#include <gtest/gtest.h>
+#include <memory>
+
+using namespace mgb;
+
+namespace {
+  // We need a struct to keep the ring and so on alive after
+  // construction - we cannot just return an object.
+  //
+  // @todo: This whole thing is fairly ridiculous - some kind of more
+  // general dependency injection mechanism might be nice here.
+  struct BuilderMaker {
+    BuilderMaker():
+      mRing(ringFromString("101 6 1\n1 1 1 1 1 1")),
+      mIdeal(*mRing),
+      mBasis(*mRing, DivisorLookup::makeFactory(*mRing, 1)->create(true, true)) {
+    }
+
+    const Poly& addBasisElement(const ::std::string& str) {
+      ::std::unique_ptr<Poly> p(new Poly(*mRing));
+      ::std::istringstream in(str);
+      p->parse(in);
+      mBasis.insert(::std::move(p));
+      return mBasis.poly(mBasis.size() - 1);
+    }
+
+    F4MatrixBuilder& create() {
+      MATHICGB_ASSERT(mBuilder.get() == 0);
+      mBuilder.reset(new F4MatrixBuilder(mBasis));
+      return *mBuilder;
+    }
+
+    const PolyRing& ring() const {return *mRing;}
+     
+  private:
+    ::std::unique_ptr<PolyRing> mRing;
+    Basis mIdeal;
+    PolyBasis mBasis;
+    ::std::unique_ptr<F4MatrixBuilder> mBuilder;
+  };
+}
+
+TEST(F4MatrixBuilder, Empty) {
+  for (int threadCount = 1; threadCount < 4; ++threadCount) {
+    mgb::tbb::task_scheduler_init scheduler(threadCount);
+    BuilderMaker maker;
+    F4MatrixBuilder& builder = maker.create();
+
+    QuadMatrix matrix;
+    builder.buildMatrixAndClear(matrix);
+    ASSERT_EQ(0, matrix.topLeft.rowCount());
+    ASSERT_EQ(0, matrix.bottomLeft.rowCount());
+    ASSERT_EQ(0, matrix.topLeft.computeColCount());
+    ASSERT_EQ(0, matrix.topRight.computeColCount());
+    ASSERT_EQ(0, matrix.leftColumnMonomials.size());
+    ASSERT_EQ(0, matrix.rightColumnMonomials.size());
+  }
+}
+
+TEST(F4MatrixBuilder, SPair) {
+  for (int threadCount = 1; threadCount < 4; ++threadCount) {
+    mgb::tbb::task_scheduler_init scheduler(threadCount);
+    BuilderMaker maker;
+    const Poly& p1 = maker.addBasisElement("a4c2-d");
+    const Poly& p2 = maker.addBasisElement("a4b+d");
+    // S-pair of p1 and p2 is -c2d-bd
+    const Poly& p3 = maker.addBasisElement("c2d+3");
+    F4MatrixBuilder& builder = maker.create();
+    builder.addSPolynomialToMatrix(p1, p2);
+    QuadMatrix qm;
+    builder.buildMatrixAndClear(qm);
+    const char* const str1 = 
+      "Left columns: c2d\n"
+      "Right columns: bd 1\n"
+      "0: 0#1   | 0: 1#3  \n"
+      "         |         \n"
+      "0: 0#100 | 0: 0#100\n";
+    const char* const str2 = 
+      "Left columns: c2d\n"
+      "Right columns: bd 1\n"
+      "0: 0#1 | 0: 0#1\n"
+      "       |       \n"
+      "0: 0#1 | 0: 1#3\n";
+    ::std::string qmStr = qm.toString();
+    ASSERT_TRUE(str1 == qmStr || str2 == qmStr) <<
+      "\n** str1: " << str1 << "\n** qm: " << qmStr;
+  }
+}
+
+TEST(F4MatrixBuilder, OneByOne) {
+  for (int threadCount = 1; threadCount < 4; ++threadCount) {
+    mgb::tbb::task_scheduler_init scheduler(threadCount);
+    BuilderMaker maker;
+    const Poly& p = maker.addBasisElement("a");
+    F4MatrixBuilder& builder = maker.create();
+    builder.addPolynomialToMatrix(p.getLeadMonomial(), p);
+    QuadMatrix qm;
+    builder.buildMatrixAndClear(qm);
+    const char* str = 
+      "Left columns: a2\n"
+      "Right columns:\n"
+      "0: 0#1 | 0:\n"
+      "       |   \n"
+      "0: 0#1 | 0:\n";
+    ASSERT_EQ(str, qm.toString()) << "** qm:\n" << qm;
+  }
+}
+
+TEST(F4MatrixBuilder, DirectReducers) {
+  for (int threadCount = 1; threadCount < 4; ++threadCount) {
+    BuilderMaker maker;
+    maker.addBasisElement("a6<0>"); // reducer == to lead term
+    maker.addBasisElement("a3b2<0>+a3c"); // reducer == to lower order term
+    maker.addBasisElement("c<0>"); // reducer divides
+    maker.addBasisElement("d2<0>"); // does not divide
+    F4MatrixBuilder& builder = maker.create();
+
+    Poly p1(builder.ring());
+    { 
+      ::std::istringstream in("a3<0>+b2+c+d");
+      p1.parse(in);
+      builder.addPolynomialToMatrix(p1.getLeadMonomial(), p1);
+    }
+
+    Poly p2(builder.ring());
+    {
+      ::std::istringstream in("a3<0>+2b2+3c+4d");
+      p2.parse(in);
+      builder.addPolynomialToMatrix(p2.getLeadMonomial(), p2);
+    }
+
+    QuadMatrix qm;
+    builder.buildMatrixAndClear(qm);
+
+    const char* str =
+      "Left columns: a6 a3b2 a3c\n"
+      "Right columns: a3d\n"
+      "0: 2#1         | 0:    \n"
+      "1: 1#1 2#1     | 1:    \n"
+      "2: 0#1         | 2:    \n"
+      "               |       \n"
+      "0: 0#1 1#1 2#1 | 0: 0#1\n"
+      "1: 0#1 1#2 2#3 | 1: 0#4\n";
+    qm = qm.toCanonical();
+    ASSERT_EQ(str, qm.toString()) << "** qm:\n" << qm;
+  }
+}
+
+TEST(F4MatrixBuilder, IteratedReducer) {
+  for (int threadCount = 1; threadCount < 4; ++threadCount) {
+    BuilderMaker maker;
+    const Poly& p1 = maker.addBasisElement("a4-a3");
+    const Poly& p2 = maker.addBasisElement("a-1");
+    F4MatrixBuilder& builder = maker.create();
+    builder.addPolynomialToMatrix(p1.getLeadMonomial(), p2);
+    QuadMatrix qm;
+    builder.buildMatrixAndClear(qm);
+    const char* str = 
+      "Left columns: a5 a4 a3 a2 a\n"
+      "Right columns: 1\n"
+      "0: 4#1       | 0: 0#100\n"
+      "1: 3#1 4#100 | 1:      \n"
+      "2: 2#1 3#100 | 2:      \n"
+      "3: 1#1 2#100 | 3:      \n"
+      "4: 0#1 1#100 | 4:      \n"
+      "             |         \n"
+      "0: 0#1 1#100 | 0:      \n";
+    ASSERT_EQ(str, qm.toCanonical().toString()) << "** qm:\n" << qm;
+  }
+}
diff --git a/src/test/F4MatrixReducer.cpp b/src/test/F4MatrixReducer.cpp
index dcf7a4d..abf27ea 100755
--- a/src/test/F4MatrixReducer.cpp
+++ b/src/test/F4MatrixReducer.cpp
@@ -1,126 +1,130 @@
-#include "mathicgb/stdinc.h"
-
-#include "mathicgb/F4MatrixReducer.hpp"
-#include "mathicgb/SparseMatrix.hpp"
-#include "mathicgb/QuadMatrix.hpp"
-#include "mathicgb/io-util.hpp"
-#include "mathicgb/Poly.hpp"
-#include <gtest/gtest.h>
-#include <sstream>
-
-TEST(F4MatrixReducer, Reduce) {
-  auto ring = ringFromString("101 6 1\n10 1 1 1 1 1");
-
-  QuadMatrix m;
-  m.ring = ring.get();
-
-  Poly p(*ring);
-  std::istringstream in("a4+a3+a2+a1+b5+b4+b3+b2+b1");
-  p.parse(in);
-  size_t count = 0;
-  for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
-    monomial mono = it.getMonomial();
-    if (count < 4)
-      m.leftColumnMonomials.push_back(mono);
-    else
-      m.rightColumnMonomials.push_back(mono);
-    ++count;
-  }
-
-  // top left
-  m.topLeft.clear();
-  m.topLeft.appendEntry(0, 1);
-  m.topLeft.appendEntry(1, 2);
-  m.topLeft.appendEntry(3, 3);
-  m.topLeft.rowDone();
-  m.topLeft.appendEntry(1, 1);
-  m.topLeft.appendEntry(2, 3);
-  m.topLeft.rowDone();
-  m.topLeft.appendEntry(2, 1);
-  m.topLeft.appendEntry(3, 7);
-  m.topLeft.rowDone();
-  m.topLeft.appendEntry(3, 1);
-  m.topLeft.rowDone();
-
-  // top right
-  m.topRight.clear();
-  m.topRight.appendEntry(2,8);
-  m.topRight.rowDone();
-  m.topRight.appendEntry(3,9);
-  m.topRight.rowDone();
-  m.topRight.appendEntry(4,10);
-  m.topRight.rowDone();
-  m.topRight.rowDone();
-
-  // bottom left
-  m.bottomLeft.clear();
-  m.bottomLeft.rowDone();
-  m.bottomLeft.appendEntry(1, 9);
-  m.bottomLeft.rowDone();
-  m.bottomLeft.appendEntry(0, 2);
-  m.bottomLeft.appendEntry(1, 99); // 100 = -2 mod 101
-  m.bottomLeft.appendEntry(2, 83); // 83 = -18 mod 101
-  m.bottomLeft.appendEntry(3, 6);
-  m.bottomLeft.rowDone();
-  m.bottomLeft.appendEntry(0, 1);
-  m.bottomLeft.appendEntry(1, 1);
-  m.bottomLeft.appendEntry(3, 24);
-  m.bottomLeft.rowDone();
-  m.bottomLeft.rowDone();
-  m.bottomLeft.appendEntry(3, 100);
-  m.bottomLeft.rowDone();
-
-  // bottom right
-  m.bottomRight.clear();
-  m.bottomRight.rowDone();
-  m.bottomRight.appendEntry(1, 2);
-  m.bottomRight.appendEntry(3, 11);
-  m.bottomRight.rowDone();
-  m.bottomRight.appendEntry(2, 16);
-  m.bottomRight.appendEntry(3, 47);
-  m.bottomRight.rowDone();
-  m.bottomRight.appendEntry(0, 1);
-  m.bottomRight.appendEntry(2, 12);
-  m.bottomRight.appendEntry(3, 13);
-  m.bottomRight.appendEntry(4, 41);
-  m.bottomRight.rowDone();
-  m.bottomRight.appendEntry(0, 2);
-  m.bottomRight.appendEntry(1, 2);
-  m.bottomRight.appendEntry(2, 8);
-  m.bottomRight.appendEntry(3, 75);
-  m.bottomRight.appendEntry(4, 90);
-  m.bottomRight.rowDone();
-  m.bottomRight.appendEntry(0, 1);
-  m.bottomRight.appendEntry(1, 1);
-  m.bottomRight.appendEntry(2, 4);
-  m.bottomRight.appendEntry(3, 88);
-  m.bottomRight.appendEntry(4, 45);
-  m.bottomRight.rowDone();
-
-  MATHICGB_ASSERT(m.debugAssertValid());
-  const char* origStr = 
-    "Left columns: a4 a3 a2 a\n"
-    "Right columns: b5 b4 b3 b2 b\n"
-    "0: 0#1 1#2 3#3       | 0: 2#8                  \n"
-    "1: 1#1 2#3           | 1: 3#9                  \n"
-    "2: 2#1 3#7           | 2: 4#10                 \n"
-    "3: 3#1               | 3:                      \n"
-    "                     |                         \n"
-    "0:                   | 0:                      \n" // zero row
-    "1: 1#9               | 1: 1#2 3#11             \n" // becomes second row
-    "2: 0#2 1#99 2#83 3#6 | 2: 2#16 3#47            \n" // zero on left red.  
-    "3: 0#1 1#1 3#24      | 3: 0#1 2#12 3#13 4#41   \n" // becomes first row
-    "4:                   | 4: 0#2 1#2 2#8 3#75 4#90\n" // zero on right red.
-    "5: 3#100             | 5: 0#1 1#1 2#4 3#88 4#45\n"; // zero on right red.
-
-  ASSERT_EQ(origStr, m.toString()) << "Printed m:\n" << m;
-
-  SparseMatrix reduced
-    (F4MatrixReducer(ring->charac()).reducedRowEchelonFormBottomRight(m));
-
-  const char* redStr =
-    "0: 0#1 2#4 3#22 4#11\n"
-    "1: 1#1 3#66 4#34\n";
-  reduced.sortRowsByIncreasingPivots();
-  ASSERT_EQ(redStr, reduced.toString()) << "Printed reduced:\n" << reduced;
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+
+#include "mathicgb/F4MatrixReducer.hpp"
+#include "mathicgb/SparseMatrix.hpp"
+#include "mathicgb/QuadMatrix.hpp"
+#include "mathicgb/io-util.hpp"
+#include "mathicgb/Poly.hpp"
+#include <gtest/gtest.h>
+#include <sstream>
+
+using namespace mgb;
+
+TEST(F4MatrixReducer, Reduce) {
+  auto ring = ringFromString("101 6 1\n10 1 1 1 1 1");
+
+  QuadMatrix m;
+  m.ring = ring.get();
+
+  Poly p(*ring);
+  ::std::istringstream in("a4+a3+a2+a1+b5+b4+b3+b2+b1");
+  p.parse(in);
+  size_t count = 0;
+  for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
+    monomial mono = it.getMonomial();
+    if (count < 4)
+      m.leftColumnMonomials.push_back(mono);
+    else
+      m.rightColumnMonomials.push_back(mono);
+    ++count;
+  }
+
+  // top left
+  m.topLeft.clear();
+  m.topLeft.appendEntry(0, 1);
+  m.topLeft.appendEntry(1, 2);
+  m.topLeft.appendEntry(3, 3);
+  m.topLeft.rowDone();
+  m.topLeft.appendEntry(1, 1);
+  m.topLeft.appendEntry(2, 3);
+  m.topLeft.rowDone();
+  m.topLeft.appendEntry(2, 1);
+  m.topLeft.appendEntry(3, 7);
+  m.topLeft.rowDone();
+  m.topLeft.appendEntry(3, 1);
+  m.topLeft.rowDone();
+
+  // top right
+  m.topRight.clear();
+  m.topRight.appendEntry(2,8);
+  m.topRight.rowDone();
+  m.topRight.appendEntry(3,9);
+  m.topRight.rowDone();
+  m.topRight.appendEntry(4,10);
+  m.topRight.rowDone();
+  m.topRight.rowDone();
+
+  // bottom left
+  m.bottomLeft.clear();
+  m.bottomLeft.rowDone();
+  m.bottomLeft.appendEntry(1, 9);
+  m.bottomLeft.rowDone();
+  m.bottomLeft.appendEntry(0, 2);
+  m.bottomLeft.appendEntry(1, 99); // 100 = -2 mod 101
+  m.bottomLeft.appendEntry(2, 83); // 83 = -18 mod 101
+  m.bottomLeft.appendEntry(3, 6);
+  m.bottomLeft.rowDone();
+  m.bottomLeft.appendEntry(0, 1);
+  m.bottomLeft.appendEntry(1, 1);
+  m.bottomLeft.appendEntry(3, 24);
+  m.bottomLeft.rowDone();
+  m.bottomLeft.rowDone();
+  m.bottomLeft.appendEntry(3, 100);
+  m.bottomLeft.rowDone();
+
+  // bottom right
+  m.bottomRight.clear();
+  m.bottomRight.rowDone();
+  m.bottomRight.appendEntry(1, 2);
+  m.bottomRight.appendEntry(3, 11);
+  m.bottomRight.rowDone();
+  m.bottomRight.appendEntry(2, 16);
+  m.bottomRight.appendEntry(3, 47);
+  m.bottomRight.rowDone();
+  m.bottomRight.appendEntry(0, 1);
+  m.bottomRight.appendEntry(2, 12);
+  m.bottomRight.appendEntry(3, 13);
+  m.bottomRight.appendEntry(4, 41);
+  m.bottomRight.rowDone();
+  m.bottomRight.appendEntry(0, 2);
+  m.bottomRight.appendEntry(1, 2);
+  m.bottomRight.appendEntry(2, 8);
+  m.bottomRight.appendEntry(3, 75);
+  m.bottomRight.appendEntry(4, 90);
+  m.bottomRight.rowDone();
+  m.bottomRight.appendEntry(0, 1);
+  m.bottomRight.appendEntry(1, 1);
+  m.bottomRight.appendEntry(2, 4);
+  m.bottomRight.appendEntry(3, 88);
+  m.bottomRight.appendEntry(4, 45);
+  m.bottomRight.rowDone();
+
+  MATHICGB_ASSERT(m.debugAssertValid());
+  const char* origStr = 
+    "Left columns: a4 a3 a2 a\n"
+    "Right columns: b5 b4 b3 b2 b\n"
+    "0: 0#1 1#2 3#3       | 0: 2#8                  \n"
+    "1: 1#1 2#3           | 1: 3#9                  \n"
+    "2: 2#1 3#7           | 2: 4#10                 \n"
+    "3: 3#1               | 3:                      \n"
+    "                     |                         \n"
+    "0:                   | 0:                      \n" // zero row
+    "1: 1#9               | 1: 1#2 3#11             \n" // becomes second row
+    "2: 0#2 1#99 2#83 3#6 | 2: 2#16 3#47            \n" // zero on left red.  
+    "3: 0#1 1#1 3#24      | 3: 0#1 2#12 3#13 4#41   \n" // becomes first row
+    "4:                   | 4: 0#2 1#2 2#8 3#75 4#90\n" // zero on right red.
+    "5: 3#100             | 5: 0#1 1#1 2#4 3#88 4#45\n"; // zero on right red.
+
+  ASSERT_EQ(origStr, m.toString()) << "Printed m:\n" << m;
+
+  SparseMatrix reduced
+    (F4MatrixReducer(ring->charac()).reducedRowEchelonFormBottomRight(m));
+
+  const char* redStr =
+    "0: 0#1 2#4 3#22 4#11\n"
+    "1: 1#1 3#66 4#34\n";
+  reduced.sortRowsByIncreasingPivots();
+  ASSERT_EQ(redStr, reduced.toString()) << "Printed reduced:\n" << reduced;
+}
diff --git a/src/test/MathicIO.cpp b/src/test/MathicIO.cpp
index f3663fa..7bd7f10 100755
--- a/src/test/MathicIO.cpp
+++ b/src/test/MathicIO.cpp
@@ -1,313 +1,317 @@
-#include "mathicgb/stdinc.h"
-#include "mathicgb/MathicIO.hpp"
-
-#include <gtest/gtest.h>
-
-TEST(MathicIO, Combined) {
-  const char* const str =
-    "32003 6\n"
-    "1 1 1 1 1 1 1\n"
-    "_revlex revcomponent\n"
-    "3\n"
-    " -bc+ad\n"
-    " -b2+af\n"
-    " -bc2+a2e\n";
-  std::istringstream inStream(str);
-  Scanner in(inStream);
-  auto p = MathicIO().readRing(true, in);
-  auto& ring = *p.first;
-  auto basis = MathicIO().readBasis(ring, false, in);
-}
-
-TEST(MathicIO, ReadWriteRing) {
-  typedef PolyRing::Monoid Monoid;
-  typedef Monoid::VarIndex VarIndex;
-  typedef Monoid::Exponent Exponent;
-  typedef PolyRing::Field BaseField;
-  typedef BaseField::RawElement RawElement;
-
-  auto check = [&](
-    const char* const inStr,
-    const char* outStr,
-    const RawElement charac,
-    const VarIndex varCount,
-    const VarIndex gradingCount,
-    const bool withComponent
-  ) {
-    for (int i = 0; i < 2; ++i) {
-      const char* str = i == 0 ? inStr : outStr;
-      if (str == 0)
-        continue;
-      Scanner in(str);
-      const auto p = MathicIO().readRing(withComponent, in);
-      const auto& monoid = p.first->monoid();
-      const auto& field = p.first->field();
-      ASSERT_EQ(charac, field.charac());
-      ASSERT_EQ(varCount, monoid.varCount());
-      ASSERT_EQ(gradingCount, monoid.gradingCount());
-      std::ostringstream out;
-      MathicIO().writeRing(*p.first, p.second, withComponent, out);
-      ASSERT_EQ(outStr, out.str());
-    }
-  };
-
-  check("101 2 1 3 4", "101 2\nrevlex 1\n 3 4\n", 101, 2, 1, false);
-  check(
-    "101 2 schreyer lex 1 3 4 _lex revcomponent",
-    "101 2\nschreyer lex 1\n 3 4\n _lex\n revcomponent\n", 101, 2, 1, true
-  );
-  check(
-    "101 2 2 component 3 4",
-    "101 2\nrevlex 2\n component\n 3 4\n", 101, 2, 2, true
-  );
-}
-
-TEST(MathicIO, ReadWriteMonomial) {
-  typedef PolyRing::Monoid Monoid;
-  typedef Monoid::VarIndex VarIndex;
-  typedef Monoid::Exponent Exponent;
-  static const auto NoComponent = static_cast<Exponent>(-1);
-
-  Monoid m(28);
-
-  // canonicalStr is str as it should appear after being read and
-  // printed. If canonicalStr is null then this is the same as str.
-  auto check = [&](
-    const char* const str,
-    const Exponent component,
-    const VarIndex var1 = -1,
-    const Exponent exp1 = -1,
-    const VarIndex var2 = -1,
-    const Exponent exp2 = -1,
-    const char* const canonicalStr = 0
-  ) {
-    const bool doComponent = component != NoComponent;
-
-    // read monomial from string
-    auto monoRead = m.alloc();
-    Scanner in(str);
-    MathicIO().readMonomial(m, doComponent, monoRead, in);
-
-    // directly make monomial
-    auto monoSet = m.alloc();
-    if (var1 != -1)
-      m.setExponent(var1, exp1, monoSet);
-    if (var2 != -1)
-      m.setExponent(var2, exp2, monoSet);
-    if (doComponent)
-      m.setComponent(component, monoSet);
-    ASSERT_TRUE(m.equal(monoRead, monoSet)) << "Str: " << str;
-
-    // print monomial
-    std::ostringstream out;
-    MathicIO().writeMonomial(m, doComponent, monoRead, out);
-    const auto correctStr = canonicalStr == 0 ? str : canonicalStr;
-    ASSERT_EQ(correctStr, out.str());
-  };
-
-  check("1", NoComponent);
-  check("1<0>", 0);
-  check("1<1>", 1);
-  check("1<999>", 999);
-
-  check("a1", NoComponent,  0,1,  -1,-1,  "a");
-  check("b10<0>", 0,   1,10);
-  check("A11", NoComponent,  26,11);
-  check("B99<1>", 1,   27,99);
-
-  check("ab", NoComponent,  0,1,  1,1);
-  check("ba", NoComponent,  0,1,  1,1,  "ab");
-  check("a0c3b1", NoComponent,  1,1,  2,3,  "bc3");
-  check("ab<2>", 2,  0,1,  1,1);
-}
-
-TEST(MathicIO, ReadWriteBasis) {
-  typedef PolyRing::Monoid Monoid;
-  typedef PolyRing::Field Field;
-  PolyRing ring(Field(101), Monoid(28));
-
-  auto check = [&](
-    const char* const inStr,
-    const char* const outStr,
-    const bool doComponent
-  ) {
-    for (int i = 0; i < 2; ++i) {
-      const char* str = i == 0 ? inStr : outStr;
-      if (str == 0)
-        continue;
-
-      Scanner in(str);
-      const auto basis = MathicIO().readBasis(ring, doComponent, in);
-      std::ostringstream out;
-      MathicIO().writeBasis(basis, doComponent, out);
-      const auto correctStr = outStr == 0 ? inStr : outStr;
-      ASSERT_EQ(correctStr, out.str());
-    }
-  };
-
-  check("0", "0\n", false);
-  check("0", "0\n", true);
-  check("1 0", "1\n 0\n", false);
-  check("1 0", "1\n 0\n", true);
-  
-  check("1 1", "1\n 1\n", false);
-  check("1 a<0>", "1\n a<0>\n", true);
-  check("2 a b", "2\n a\n b\n", false);
-}
-
-TEST(MathicIO, ReadWritePoly) {
-  typedef PolyRing::Monoid Monoid;
-  typedef PolyRing::Field Field;
-  PolyRing ring(Field(101), Monoid(28));
-
-  auto check = [&](
-    const char* const inStr,
-    const char* const outStr,
-    const bool doComponent
-  ) {
-    for (int i = 0; i < 2; ++i) {
-      const char* str = i == 0 ? inStr : outStr;
-      if (str == 0)
-        continue;
-
-      Scanner in(str);
-      const auto poly = MathicIO().readPoly(ring, doComponent, in);
-      std::ostringstream out;
-      MathicIO().writePoly(poly, doComponent, out);
-      const auto correctStr = outStr == 0 ? inStr : outStr;
-      ASSERT_EQ(correctStr, out.str());
-    }
-  };
-
-  check("+0", "0", false);
-  check("-0", "0", false);
-  check("+1", "1", false);
-  check("\t  a\t", "a", false);
-  check("3a+1b5+2c6", "3a+b5+2c6", false);
-
-  check("+0", "0", true);
-  check("-0", "0", true);
-  check("+1<5>", "1<5>", true);
-  check("\t  a<0>\t", "a<0>", true);
-  check("3a<1>+1b5<2>+2c6<3>", "3a<1>+b5<2>+2c6<3>", true);
-}
-
-TEST(MathicIO, ReadWriteTerm) {
-  typedef PolyRing::Monoid Monoid;
-  typedef Monoid::VarIndex VarIndex;
-  typedef Monoid::Exponent Exponent;
-  typedef PolyRing::Field Field;
-  typedef Field::Element Coefficient;
-  typedef Field::RawElement RawCoefficient;
-  static const auto NoComponent = static_cast<Exponent>(-1);
-
-  PolyRing ring(Field(101), Monoid(28));
-  auto&& m = ring.monoid();
-  auto&& f = ring.field();
-
-  auto check = [&](
-    const char* const inStr,
-    const char* const outStr,
-    const bool doComponent,
-    const RawCoefficient coef
-  ) {
-    for (int i = 0; i < 2; ++i) {
-      const char* str = i == 0 ? inStr : outStr;
-      if (str == 0)
-        continue;
-
-      // read term from string
-      auto monoRead = m.alloc();
-      Coefficient readCoef = f.zero();
-      Scanner in(str);
-      MathicIO().readTerm(ring, doComponent, readCoef, monoRead, in);
-      
-      ASSERT_EQ(coef, readCoef.value());
-
-      // print monomial
-      std::ostringstream out;
-      MathicIO().writeTerm(ring, doComponent, readCoef, monoRead, out);
-      const auto correctStr = outStr == 0 ? inStr : outStr;
-      ASSERT_EQ(correctStr, out.str());
-    }
-  };
-
-  check("1", 0, false, 1);
-  check("-1", "100", false, f.minusOne().value());
-  check("+1", "1", false, 1);
-  check("2", 0, false, 2);
-  check("+102", "1", false, 1);
-
-  check("1<0>", 0, true, 1);
-  check("+1<2>", "1<2>", true, 1);
-  check("2<3>", 0, true, 2);
-  check("+3<4>", "3<4>", true, 3);
-  check("-3<4>", "98<4>", true, f.negative(f.toElement(3)).value());
-
-  check("+1a<0>", "a<0>", true, 1);
-  check("+2b", "2b", false, 2);
-}
-
-TEST(MathicIO, ReadWriteBaseField) {
-  Scanner in("101");
-  auto field = MathicIO().readBaseField(in);
-  ASSERT_EQ(101, field.charac());
-  std::ostringstream out;
-  MathicIO().writeBaseField(field, out);
-  ASSERT_EQ("101", out.str());
-}
-
-TEST(MathicIO, ReadWriteOrder) {
-  typedef PolyRing::Monoid Monoid;
-  typedef Monoid::VarIndex VarIndex;
-
-  const auto check = [](
-    const char* const inStr,
-    const char* const outStr,
-    const VarIndex varCount,
-    const VarIndex gradingCount,
-    const bool withComponent = false,
-    const bool componentsAscendingDesired = true,
-    const bool schreyering = false
-  ) -> void {
-    for (int i = 0; i < 2; ++i) {
-      const char* str = i == 0 ? inStr : outStr;
-      if (str == 0)
-        continue;
-
-      Scanner in(str);
-      const auto order = MathicIO().readOrder(varCount, withComponent, in);
-      ASSERT_EQ(varCount, order.varCount());
-      ASSERT_EQ(gradingCount, order.gradingCount());
-      ASSERT_EQ(componentsAscendingDesired, order.componentsAscendingDesired());
-      ASSERT_EQ(schreyering, order.schreyering()) << inStr;
-
-      std::ostringstream out;
-      MathicIO().writeOrder(order, withComponent, out);
-      ASSERT_EQ(outStr, out.str());
-    }
-  };
-  check("0\n", "revlex 0\n", 0, 0);
-  check("1\n 2\n", "revlex 1\n 2\n", 1, 1);
-  check("2\n 3\n 4\n", "revlex 2\n 3\n 4\n", 1, 2);
-  check("2\n 3 4\n 5 6\n", "revlex 2\n 3 4\n 5 6\n", 2, 2);
-  check("1\n 1 1 1 1\n", "revlex 1\n 1 1 1 1\n", 4, 1);
-
-  check("lex 0", "lex 0\n", 0, 0);
-  check("lex 1 2", "lex 1\n 2\n", 1, 1);
-  check("lex 2 3 4", "lex 2\n 3\n 4\n", 1, 2);
-  check("lex 2 3 4 5 6", "lex 2\n 3 4\n 5 6\n", 2, 2);
-  check("lex 1 1 1 1 1", "lex 1\n 1 1 1 1\n", 4, 1);
-
-  check("2 component\n 5 6\n", "revlex 2\n component\n 5 6\n", 2, 2, 1, 1, 0);
-  check("2 3 4\nrevcomponent\n","revlex 2\n 3 4\n revcomponent\n",2,2, 1,0,0);
-  check("lex 1 component", "lex 0\n", 0, 0,  1, 1, 0);
-  check("lex 1 revcomponent", "lex 1\n revcomponent\n", 1, 1, 1, 0, 0);
-  check("lex 1 revcomponent", "lex 1\n revcomponent\n", 5, 1, 1, 0, 0);
-
-  check(
-    "schreyer lex 1 1 _revlex revcomponent",
-    "schreyer revlex 1\n 1\n _revlex\n revcomponent\n",
-    1, 1, 1, 0, 1
-  );
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+#include "mathicgb/MathicIO.hpp"
+
+#include <gtest/gtest.h>
+
+using namespace mgb;
+
+TEST(MathicIO, Combined) {
+  const char* const str =
+    "32003 6\n"
+    "1 1 1 1 1 1 1\n"
+    "_revlex revcomponent\n"
+    "3\n"
+    " -bc+ad\n"
+    " -b2+af\n"
+    " -bc2+a2e\n";
+  std::istringstream inStream(str);
+  Scanner in(inStream);
+  auto p = MathicIO().readRing(true, in);
+  auto& ring = *p.first;
+  auto basis = MathicIO().readBasis(ring, false, in);
+}
+
+TEST(MathicIO, ReadWriteRing) {
+  typedef PolyRing::Monoid Monoid;
+  typedef Monoid::VarIndex VarIndex;
+  typedef Monoid::Exponent Exponent;
+  typedef PolyRing::Field BaseField;
+  typedef BaseField::RawElement RawElement;
+
+  auto check = [&](
+    const char* const inStr,
+    const char* outStr,
+    const RawElement charac,
+    const VarIndex varCount,
+    const VarIndex gradingCount,
+    const bool withComponent
+  ) {
+    for (int i = 0; i < 2; ++i) {
+      const char* str = i == 0 ? inStr : outStr;
+      if (str == 0)
+        continue;
+      Scanner in(str);
+      const auto p = MathicIO().readRing(withComponent, in);
+      const auto& monoid = p.first->monoid();
+      const auto& field = p.first->field();
+      ASSERT_EQ(charac, field.charac());
+      ASSERT_EQ(varCount, monoid.varCount());
+      ASSERT_EQ(gradingCount, monoid.gradingCount());
+      std::ostringstream out;
+      MathicIO().writeRing(*p.first, p.second, withComponent, out);
+      ASSERT_EQ(outStr, out.str());
+    }
+  };
+
+  check("101 2 1 3 4", "101 2\nrevlex 1\n 3 4\n", 101, 2, 1, false);
+  check(
+    "101 2 schreyer lex 1 3 4 _lex revcomponent",
+    "101 2\nschreyer lex 1\n 3 4\n _lex\n revcomponent\n", 101, 2, 1, true
+  );
+  check(
+    "101 2 2 component 3 4",
+    "101 2\nrevlex 2\n component\n 3 4\n", 101, 2, 2, true
+  );
+}
+
+TEST(MathicIO, ReadWriteMonomial) {
+  typedef PolyRing::Monoid Monoid;
+  typedef Monoid::VarIndex VarIndex;
+  typedef Monoid::Exponent Exponent;
+  static const auto NoComponent = static_cast<Exponent>(-1);
+
+  Monoid m(28);
+
+  // canonicalStr is str as it should appear after being read and
+  // printed. If canonicalStr is null then this is the same as str.
+  auto check = [&](
+    const char* const str,
+    const Exponent component,
+    const VarIndex var1 = -1,
+    const Exponent exp1 = -1,
+    const VarIndex var2 = -1,
+    const Exponent exp2 = -1,
+    const char* const canonicalStr = 0
+  ) {
+    const bool doComponent = component != NoComponent;
+
+    // read monomial from string
+    auto monoRead = m.alloc();
+    Scanner in(str);
+    MathicIO().readMonomial(m, doComponent, monoRead, in);
+
+    // directly make monomial
+    auto monoSet = m.alloc();
+    if (var1 != -1)
+      m.setExponent(var1, exp1, monoSet);
+    if (var2 != -1)
+      m.setExponent(var2, exp2, monoSet);
+    if (doComponent)
+      m.setComponent(component, monoSet);
+    ASSERT_TRUE(m.equal(monoRead, monoSet)) << "Str: " << str;
+
+    // print monomial
+    std::ostringstream out;
+    MathicIO().writeMonomial(m, doComponent, monoRead, out);
+    const auto correctStr = canonicalStr == 0 ? str : canonicalStr;
+    ASSERT_EQ(correctStr, out.str());
+  };
+
+  check("1", NoComponent);
+  check("1<0>", 0);
+  check("1<1>", 1);
+  check("1<999>", 999);
+
+  check("a1", NoComponent,  0,1,  -1,-1,  "a");
+  check("b10<0>", 0,   1,10);
+  check("A11", NoComponent,  26,11);
+  check("B99<1>", 1,   27,99);
+
+  check("ab", NoComponent,  0,1,  1,1);
+  check("ba", NoComponent,  0,1,  1,1,  "ab");
+  check("a0c3b1", NoComponent,  1,1,  2,3,  "bc3");
+  check("ab<2>", 2,  0,1,  1,1);
+}
+
+TEST(MathicIO, ReadWriteBasis) {
+  typedef PolyRing::Monoid Monoid;
+  typedef PolyRing::Field Field;
+  PolyRing ring(Field(101), Monoid(28));
+
+  auto check = [&](
+    const char* const inStr,
+    const char* const outStr,
+    const bool doComponent
+  ) {
+    for (int i = 0; i < 2; ++i) {
+      const char* str = i == 0 ? inStr : outStr;
+      if (str == 0)
+        continue;
+
+      Scanner in(str);
+      const auto basis = MathicIO().readBasis(ring, doComponent, in);
+      std::ostringstream out;
+      MathicIO().writeBasis(basis, doComponent, out);
+      const auto correctStr = outStr == 0 ? inStr : outStr;
+      ASSERT_EQ(correctStr, out.str());
+    }
+  };
+
+  check("0", "0\n", false);
+  check("0", "0\n", true);
+  check("1 0", "1\n 0\n", false);
+  check("1 0", "1\n 0\n", true);
+  
+  check("1 1", "1\n 1\n", false);
+  check("1 a<0>", "1\n a<0>\n", true);
+  check("2 a b", "2\n a\n b\n", false);
+}
+
+TEST(MathicIO, ReadWritePoly) {
+  typedef PolyRing::Monoid Monoid;
+  typedef PolyRing::Field Field;
+  PolyRing ring(Field(101), Monoid(28));
+
+  auto check = [&](
+    const char* const inStr,
+    const char* const outStr,
+    const bool doComponent
+  ) {
+    for (int i = 0; i < 2; ++i) {
+      const char* str = i == 0 ? inStr : outStr;
+      if (str == 0)
+        continue;
+
+      Scanner in(str);
+      const auto poly = MathicIO().readPoly(ring, doComponent, in);
+      std::ostringstream out;
+      MathicIO().writePoly(poly, doComponent, out);
+      const auto correctStr = outStr == 0 ? inStr : outStr;
+      ASSERT_EQ(correctStr, out.str());
+    }
+  };
+
+  check("+0", "0", false);
+  check("-0", "0", false);
+  check("+1", "1", false);
+  check("\t  a\t", "a", false);
+  check("3a+1b5+2c6", "3a+b5+2c6", false);
+
+  check("+0", "0", true);
+  check("-0", "0", true);
+  check("+1<5>", "1<5>", true);
+  check("\t  a<0>\t", "a<0>", true);
+  check("3a<1>+1b5<2>+2c6<3>", "3a<1>+b5<2>+2c6<3>", true);
+}
+
+TEST(MathicIO, ReadWriteTerm) {
+  typedef PolyRing::Monoid Monoid;
+  typedef Monoid::VarIndex VarIndex;
+  typedef Monoid::Exponent Exponent;
+  typedef PolyRing::Field Field;
+  typedef Field::Element Coefficient;
+  typedef Field::RawElement RawCoefficient;
+  static const auto NoComponent = static_cast<Exponent>(-1);
+
+  PolyRing ring(Field(101), Monoid(28));
+  auto&& m = ring.monoid();
+  auto&& f = ring.field();
+
+  auto check = [&](
+    const char* const inStr,
+    const char* const outStr,
+    const bool doComponent,
+    const RawCoefficient coef
+  ) {
+    for (int i = 0; i < 2; ++i) {
+      const char* str = i == 0 ? inStr : outStr;
+      if (str == 0)
+        continue;
+
+      // read term from string
+      auto monoRead = m.alloc();
+      Coefficient readCoef = f.zero();
+      Scanner in(str);
+      MathicIO().readTerm(ring, doComponent, readCoef, monoRead, in);
+      
+      ASSERT_EQ(coef, readCoef.value());
+
+      // print monomial
+      std::ostringstream out;
+      MathicIO().writeTerm(ring, doComponent, readCoef, monoRead, out);
+      const auto correctStr = outStr == 0 ? inStr : outStr;
+      ASSERT_EQ(correctStr, out.str());
+    }
+  };
+
+  check("1", 0, false, 1);
+  check("-1", "100", false, f.minusOne().value());
+  check("+1", "1", false, 1);
+  check("2", 0, false, 2);
+  check("+102", "1", false, 1);
+
+  check("1<0>", 0, true, 1);
+  check("+1<2>", "1<2>", true, 1);
+  check("2<3>", 0, true, 2);
+  check("+3<4>", "3<4>", true, 3);
+  check("-3<4>", "98<4>", true, f.negative(f.toElement(3)).value());
+
+  check("+1a<0>", "a<0>", true, 1);
+  check("+2b", "2b", false, 2);
+}
+
+TEST(MathicIO, ReadWriteBaseField) {
+  Scanner in("101");
+  auto field = MathicIO().readBaseField(in);
+  ASSERT_EQ(101, field.charac());
+  std::ostringstream out;
+  MathicIO().writeBaseField(field, out);
+  ASSERT_EQ("101", out.str());
+}
+
+TEST(MathicIO, ReadWriteOrder) {
+  typedef PolyRing::Monoid Monoid;
+  typedef Monoid::VarIndex VarIndex;
+
+  const auto check = [](
+    const char* const inStr,
+    const char* const outStr,
+    const VarIndex varCount,
+    const VarIndex gradingCount,
+    const bool withComponent = false,
+    const bool componentsAscendingDesired = true,
+    const bool schreyering = false
+  ) -> void {
+    for (int i = 0; i < 2; ++i) {
+      const char* str = i == 0 ? inStr : outStr;
+      if (str == 0)
+        continue;
+
+      Scanner in(str);
+      const auto order = MathicIO().readOrder(varCount, withComponent, in);
+      ASSERT_EQ(varCount, order.varCount());
+      ASSERT_EQ(gradingCount, order.gradingCount());
+      ASSERT_EQ(componentsAscendingDesired, order.componentsAscendingDesired());
+      ASSERT_EQ(schreyering, order.schreyering()) << inStr;
+
+      std::ostringstream out;
+      MathicIO().writeOrder(order, withComponent, out);
+      ASSERT_EQ(outStr, out.str());
+    }
+  };
+  check("0\n", "revlex 0\n", 0, 0);
+  check("1\n 2\n", "revlex 1\n 2\n", 1, 1);
+  check("2\n 3\n 4\n", "revlex 2\n 3\n 4\n", 1, 2);
+  check("2\n 3 4\n 5 6\n", "revlex 2\n 3 4\n 5 6\n", 2, 2);
+  check("1\n 1 1 1 1\n", "revlex 1\n 1 1 1 1\n", 4, 1);
+
+  check("lex 0", "lex 0\n", 0, 0);
+  check("lex 1 2", "lex 1\n 2\n", 1, 1);
+  check("lex 2 3 4", "lex 2\n 3\n 4\n", 1, 2);
+  check("lex 2 3 4 5 6", "lex 2\n 3 4\n 5 6\n", 2, 2);
+  check("lex 1 1 1 1 1", "lex 1\n 1 1 1 1\n", 4, 1);
+
+  check("2 component\n 5 6\n", "revlex 2\n component\n 5 6\n", 2, 2, 1, 1, 0);
+  check("2 3 4\nrevcomponent\n","revlex 2\n 3 4\n revcomponent\n",2,2, 1,0,0);
+  check("lex 1 component", "lex 0\n", 0, 0,  1, 1, 0);
+  check("lex 1 revcomponent", "lex 1\n revcomponent\n", 1, 1, 1, 0, 0);
+  check("lex 1 revcomponent", "lex 1\n revcomponent\n", 5, 1, 1, 0, 0);
+
+  check(
+    "schreyer lex 1 1 _revlex revcomponent",
+    "schreyer revlex 1\n 1\n _revlex\n revcomponent\n",
+    1, 1, 1, 0, 1
+  );
+}
diff --git a/src/test/MonoMonoid.cpp b/src/test/MonoMonoid.cpp
index e0ca013..20ad8c0 100755
--- a/src/test/MonoMonoid.cpp
+++ b/src/test/MonoMonoid.cpp
@@ -1,865 +1,868 @@
-#include "mathicgb/stdinc.h"
-
-#include "mathicgb/MonoMonoid.hpp"
-#include <gtest/gtest.h>
-#include <sstream>
-
-
-// Do all-pairs testing -- see monoidPict.in. Especially see that file before
-// editing this list of types.
-typedef ::testing::Types<
-  MonoMonoid<int32,1,1,1>,
-  MonoMonoid<int32,0,1,1>,
-  MonoMonoid<int32,0,0,1>,
-  MonoMonoid<int32,0,0,0>,
-  MonoMonoid<int16,1,1,1>,
-  MonoMonoid<int16,0,1,1>,
-  MonoMonoid<int16,0,0,1>,
-  MonoMonoid<int16,0,0,0>,
-  MonoMonoid<int8,1,0,1>,
-  MonoMonoid<int8,0,1,0>,
-  MonoMonoid<int32,1,1,0>
-> MonoidTypes;
-
-template <typename T>
-class Monoid : public ::testing::Test {};
-TYPED_TEST_CASE(Monoid, MonoidTypes);
-
-// expect(i,j) encodes a matrix with interesting bit patterns that
-// are supposed to be likely to surface errors in how monomials are
-// stored inside a vector.
-uint32 expect(size_t mono, size_t var, size_t varCount) {
-  const auto unique = (static_cast<uint32>(var + varCount * mono + 1) % 127);
-
-  while (true) {
-    // 000
-    if (mono == 0)
-      return 0;
-    --mono;
-
-    // 100
-    // 010
-    // 001
-    if (mono < varCount)
-      return var == mono ? unique : 0;
-    mono -= varCount;
-
-    // 000
-    // 100
-    // 110
-    // 111
-    if (mono < varCount + 1)
-      return var < mono ? unique : 0;
-    mono -= varCount + 1;
-
-    // 111
-    // 011
-    // 001
-    // 000
-    if (mono < varCount + 1)
-      return var >= mono ? unique : 0;
-    mono -= varCount + 1;
-
-    // 101
-    // 010
-    if (mono < 4)
-      return (var % 2) == (mono % 2) ? unique : 0;
-    mono -= 4;
-
-    // 100100
-    // 010010
-    // 001001
-    if (mono < 6)
-      return (var % 3) == (mono % 3) ? unique : 0;
-    mono -= 6;
-
-    // mix the patterns
-    mono += var % 17;
-  }
-};
-
-TYPED_TEST(Monoid, VarCount) {
-  typedef TypeParam Monoid;
-  ASSERT_EQ(0, Monoid(0).varCount());
-  ASSERT_EQ(1000 * 1000, Monoid(1000 * 1000).varCount());
-  ASSERT_EQ(1, Monoid(1).varCount());
-  ASSERT_EQ(2, Monoid(2).varCount());
-  ASSERT_EQ(12, Monoid(12).varCount());
-}
-
-TYPED_TEST(Monoid, MonoVector) {
-  typedef TypeParam Monoid;
-  typedef typename Monoid::VarIndex VarIndex;
-  typedef typename Monoid::MonoVector MonoVector;
-
-  Monoid monoid(13);
-  MonoVector v(monoid);
-  MonoVector v2(monoid);
-  ASSERT_EQ(v2.monoid(), monoid);
-  const auto varCount = monoid.varCount();
-
-  ASSERT_TRUE(v.empty());
-  size_t count = 1000;
-
-
-  // Not a correctness error, but empty vectors should preferably not
-  // use any memory.
-  ASSERT_EQ(0, v.memoryBytesUsed());
-
-  for (size_t i = 0; i < count; ++i) {
-    ASSERT_EQ(i, v.size());
-    v.push_back(); // push_back, no param
-    ASSERT_GT(v.memoryBytesUsed(), 0);
-    ASSERT_FALSE(v.empty()); // empty
-    ASSERT_EQ(i + 1, v.size()); // size
-
-
-    ASSERT_TRUE(monoid.isIdentity(v.back())); // isIdentity true, back non-const
-    bool allZero = true;
-    for (VarIndex var = 0; var < varCount; ++var) {
-      const auto exponent = expect(i, var, varCount);
-      if (exponent != 0) {
-	allZero = false;
-	monoid.setExponent(var, exponent, v.back());
-      }
-    }
-    ASSERT_EQ(allZero, monoid.isIdentity(v.back())); // isIdentity false
-    v2.push_back(v.back()); // push_back with param
-    ASSERT_TRUE(monoid.equal(v.back(), v2.back()));
-  }
-  auto it = v.begin();
-  ASSERT_EQ(it, v.cbegin());
-  for (size_t i = 0; i < count; ++i, ++it) {
-    typename MonoVector::const_iterator tmp;
-    tmp = it;
-    ASSERT_EQ(tmp, it);
-    ASSERT_TRUE(v.end() != it);
-
-    for (VarIndex var = 0; var < monoid.varCount(); ++var) {
-      ASSERT_EQ(expect(i, var, varCount), monoid.exponent(*it, var));
-    }
-  }
-  ASSERT_EQ(v.end(), it);
-  ASSERT_EQ(v.cend(), it);
-
-  ASSERT_EQ(v, v2); // operator== true
-  monoid.setExponent(0, 1 + monoid.exponent(v2.back(), 0), v2.back());
-  ASSERT_TRUE(v != v2); // operator!=, true, same length
-
-  auto& vc = const_cast<const MonoVector&>(v);
-  ASSERT_TRUE(monoid.equal(v.front(), *v2.begin())); // front, non-const
-  ASSERT_TRUE(monoid.equal(vc.front(), *v2.begin())); // front, const
-  ASSERT_TRUE(monoid.equal(vc.back(), v.back())); // back, non-const
-
-  auto v3(v2); // copy constructor
-  ASSERT_EQ(v3.monoid(), monoid);
-  ASSERT_TRUE(v != v3 && v2 == v3);
-  v2.swap(v); // member swap
-  ASSERT_TRUE(v == v3 && v2 != v3);
-  std::swap(v, v2); // std::swap
-  ASSERT_TRUE(v != v3 && v2 == v3);
-  using std::swap;
-  swap(v, v2); // let compiler decide which swap to use
-  ASSERT_TRUE(v == v3 && v2 != v3);
-  swap(v, v2); // get back to original state
-  ASSERT_TRUE(v != v3 && v2 == v3);
-
-  ASSERT_FALSE(v3 != v2); // operator!=, false, same length
-  v3.push_back();
-  ASSERT_TRUE(v3 != v2); // operator!=, true, different length
-  
-
-  ASSERT_FALSE(v3 == v);
-  v3 = v; // copy assignment
-  ASSERT_EQ(v3.monoid(), monoid);
-  ASSERT_EQ(v3, v);
-
-  ASSERT_FALSE(v3.empty());
-  v2 = std::move(v3); // move assignment
-  ASSERT_EQ(v2.monoid(), monoid);
-  ASSERT_EQ(v2, v);
-  ASSERT_TRUE(v3.empty());
-
-  ASSERT_FALSE(v2.empty());
-  auto v4(std::move(v2)); // move constructor
-  ASSERT_EQ(v4.monoid(), monoid);
-  ASSERT_TRUE(v2.empty());
-  ASSERT_EQ(v4, v);
-
-  ASSERT_FALSE(v.empty());
-  v.clear();
-  ASSERT_TRUE(v.empty());
-}
-
-TYPED_TEST(Monoid, ReadWriteMonoid) {
-  typedef TypeParam Monoid;
-  typedef typename Monoid::VarIndex VarIndex;
-
-  const auto check = [](
-    const char* const inStr,
-    const char* const outStr,
-    const VarIndex varCount,
-    const VarIndex gradingCount
-    ) -> void {
-    for (int i = 0; i < 2; ++i) {
-      const char* str = i == 0 ? inStr : outStr;
-      if (str == 0)
-        continue;
-
-      std::istringstream in(str);
-      const auto p = Monoid::readMonoid(in);
-      const auto& m = p.first;
-
-      std::ostringstream out;
-      m.printMonoid(p.second.first, out);
-      ASSERT_EQ(outStr, out.str());
-      ASSERT_EQ(varCount, m.varCount());
-      ASSERT_EQ(gradingCount, m.gradingCount());
-    }
-  };
-  check("0 0\n", "0\nrevlex 0\n", 0, 0);
-  check("1 1\n 2\n", "1\nrevlex 1\n 2\n", 1, 1);
-  check("1 2\n 3\n 4\n", "1\nrevlex 2\n 3\n 4\n", 1, 2);
-  check("2 2\n 3 4\n 5 6\n", "2\nrevlex 2\n 3 4\n 5 6\n", 2, 2);
-  check("4 1\n 1 1 1 1\n", "4\nrevlex 1\n 1 1 1 1\n", 4, 1);
-
-  check("0 lex 0", "0\nlex 0\n", 0, 0);
-  check("1 lex 1 2", "1\nlex 1\n 2\n", 1, 1);
-  check("1 lex 2 3 4", "1\nlex 2\n 3\n 4\n", 1, 2);
-  check("2 lex 2 3 4 5 6", "2\nlex 2\n 3 4\n 5 6\n", 2, 2);
-  check("4 lex 1 1 1 1 1", "4\nlex 1\n 1 1 1 1\n", 4, 1);
-
-  if (Monoid::HasComponent) {
-    check("2 2\n component\n 5 6\n", "2\nrevlex 2\n component\n 5 6\n", 2, 2);
-    check
-      ("2 2\n 3 4\n revcomponent\n","2\nrevlex 2\n 3 4\n revcomponent\n", 2, 2);
-    check("0 lex 1 component", "0\nlex 0\n", 0, 0);
-    check("1 lex 1 revcomponent", "1\nlex 1\n revcomponent\n", 1, 1);
-    check("5 lex 1 revcomponent", "5\nlex 1\n revcomponent\n", 5, 1);
-  }
-}
-
-TYPED_TEST(Monoid, MonoPool) {
-  typedef TypeParam Monoid;
-  typedef typename Monoid::VarIndex VarIndex;
-  typedef typename Monoid::Mono Mono;
-
-  for (int q = 0; q < 2; ++q) {
-    Monoid monoid(13);
-    typename Monoid::MonoPool pool(monoid);
-    const auto varCount = monoid.varCount();
-
-    const auto count = 1000;
-    std::vector<Mono> monos;
-    for (int i = 0; i < count; ++i) {
-      pool.alloc();
-      pool.free(pool.alloc());
-      auto m1 = pool.alloc();
-      ASSERT_TRUE(monoid.isIdentity(m1));
-      auto m2 = pool.alloc();
-      ASSERT_TRUE(monoid.isIdentity(m2));
-      for (VarIndex var = 0; var < varCount; ++var) {
-        monoid.setExponent(var, 1, m1);
-        monoid.setExponent(var, 1, m2);
-      }
-      if (i > 10) {
-        using std::swap;
-        swap(m2, monos[i - 10]);
-      }
-      monos.emplace_back(std::move(m1));
-    }
-    
-    // This ensures that we get to each entry in monos exactly once.
-    MATHICGB_ASSERT((count % 17) != 0); 
-    int i = 0;
-    do {
-      MATHICGB_ASSERT(!monos[i].isNull());
-      ASSERT_FALSE(monoid.isIdentity(monos[i]));
-      pool.free(std::move(monos[i]));
-      ASSERT_TRUE(monos[i].isNull());
-      pool.free(std::move(monos[i]));
-      ASSERT_TRUE(monos[i].isNull());
-      i = (i + 17) % count;
-    } while (i != 0);
-
-    // If the ordering of monomials inside the pool has anything to do with
-    // allocation and deallocation order, then the monomials inside the
-    // pool are at this point all jumbled around. All the entries were also
-    // non-zero before, so we test that new allocations are the identity.
-
-    for (int i = 0; i < count; ++i) {
-      monos[i] = pool.alloc();
-      ASSERT_TRUE(monoid.isIdentity(monos[i]));
-      for (VarIndex var = 0; var < varCount; ++var)
-        monoid.setExponent(var, expect(i, var, varCount), monos[i]);
-    }
-    for (int i = 0; i < count; ++i) {
-      for (VarIndex var = 0; var < varCount; ++var) {
-        ASSERT_EQ(expect(i, var, varCount), monoid.exponent(monos[i], var));
-      }
-    }
-    // everything should be free'd now. Let's do all that again.
-  }
-}
-
-namespace {
-  template<class M>
-  typename M::MonoVector parseVector(M& monoid, const char* str) {
-    typename M::MonoVector v(monoid);
-    std::istringstream in(str);
-    v.parseM2(in);
-    return v;
-  }
-}
-
-TYPED_TEST(Monoid, ParsePrintM2) {
-  typedef TypeParam Monoid;
-  Monoid m(100);
-  std::string str = "1 a z A Z ab a2 a2b ab2 a20b30";
-  if (Monoid::HasComponent)
-    str += " 1<1> a<2> a2<3> ab<11>\n";
-  else
-    str += '\n';
-  auto v2 = parseVector(m, str.c_str());
-  std::ostringstream v2Out;
-  v2.printM2(v2Out);
-  ASSERT_EQ(str, v2Out.str());
-
-  decltype(v2) v(m);
-  v.push_back(); // 1
-
-  v.push_back(); // a
-  m.setExponent(0, 1, v.back());
- 
-  v.push_back(); // z
-  m.setExponent(25, 1, v.back());
-
-  v.push_back(); // A
-  m.setExponent(26, 1, v.back());
-
-  v.push_back(); // Z
-  m.setExponent(51, 1, v.back());
-
-  v.push_back(); // ab
-  m.setExponent(0, 1, v.back());
-  m.setExponent(1, 1, v.back());
-
-  v.push_back(); // a2
-  m.setExponent(0, 2, v.back());
-
-  v.push_back(); // a2b
-  m.setExponent(0, 2, v.back());
-  m.setExponent(1, 1, v.back());
-
-  v.push_back(); // ab2
-  m.setExponent(0, 1, v.back());
-  m.setExponent(1, 2, v.back());
-
-  v.push_back(); // a20b30
-  m.setExponent(0, 20, v.back());
-  m.setExponent(1, 30, v.back());
-
-  if (Monoid::HasComponent) {
-    v.push_back(); // 1<1>
-    m.setComponent(1, v.back());
-
-    v.push_back(); // a<2>
-    m.setComponent(2, v.back());
-    m.setExponent(0, 1, v.back());
-
-    v.push_back(); // a2<3>
-    m.setComponent(3, v.back());
-    m.setExponent(0, 2, v.back());
-
-    v.push_back(); // ab<11>
-    m.setComponent(11, v.back());
-    m.setExponent(0, 1, v.back());
-    m.setExponent(1, 1, v.back());
-  }
-
-  std::ostringstream vOut;
-  v.printM2(vOut);
-  ASSERT_EQ(str, vOut.str());
-  
-  ASSERT_EQ(v, v2);
-}
-
-
-TYPED_TEST(Monoid, MultiplyDivide) {
-  typedef TypeParam Monoid;
-  Monoid m(49);
-  typename Monoid::MonoPool pool(m);
-  auto mono = pool.alloc();
-  auto check = [&](const char* const str, const bool component) -> void {
-    if (component && !Monoid::HasComponent)
-      return;
-    auto v = parseVector(m, str);
-    MATHICGB_ASSERT(v.size() == 3);
-    const auto& a = v.front();
-    const auto& b = *++v.begin();
-    const auto& c = v.back();
-    ASSERT_EQ(m.hashOfProduct(a, b), m.hash(c));
-    ASSERT_EQ(m.hashOfProduct(a, b), m.hashOfProduct(b, a));
-
-    // isProductOf
-    ASSERT_TRUE(m.isProductOf(a, b, c));
-    ASSERT_TRUE(m.isProductOfHintTrue(a, b, c));
-    ASSERT_TRUE(m.isTwoProductsOfHintTrue(a, a, b, c, c));
-    
-
-    // a*b == c using multiply
-    m.multiply(a, b, mono);
-    ASSERT_TRUE(m.equal(c, mono));
-    ASSERT_TRUE(m.compare(c, mono) == Monoid::EqualTo);
-    ASSERT_EQ(m.hash(c), m.hash(mono));
-
-    // c/a == b using divide
-    m.divide(a, c, mono);
-    ASSERT_TRUE(m.equal(b, mono));
-    ASSERT_TRUE(m.compare(b, mono) == Monoid::EqualTo);
-    ASSERT_EQ(m.hash(b), m.hash(mono));
-
-    // c/b == a using divideInPlace
-    m.copy(c, mono);
-    m.divideInPlace(b, mono);
-    ASSERT_TRUE(m.equal(a, mono));
-    ASSERT_TRUE(m.compare(a, mono) == Monoid::EqualTo);
-    ASSERT_EQ(m.hash(a), m.hash(mono));
-
-    // a*b == c using multiplyInPlace
-    m.copy(a, mono);
-    m.multiplyInPlace(b, mono);
-    ASSERT_TRUE(m.equal(c, mono));
-    ASSERT_TRUE(m.compare(c, mono) == Monoid::EqualTo);
-    ASSERT_EQ(m.hash(c), m.hash(mono));
-
-    // divides, check properties that mono=a*b should have
-    ASSERT_TRUE(m.divides(mono, c));
-    ASSERT_TRUE(m.divides(c, mono));
-    ASSERT_TRUE(m.divides(a, mono));
-    ASSERT_TRUE(m.divides(b, mono));
-
-    // divides, general
-    ASSERT_TRUE(m.divides(m, mono, c));
-    ASSERT_TRUE(m.divides(m, c, mono));
-    ASSERT_TRUE(m.divides(m, a, mono));
-    ASSERT_TRUE(m.divides(m, b, mono));
-
-    if (!m.isIdentity(a)) {
-      ASSERT_TRUE(m.lessThan(b, mono));
-      ASSERT_FALSE(m.lessThan(mono, b));
-      ASSERT_TRUE(m.compare(mono, b) == Monoid::GreaterThan);
-      ASSERT_FALSE(m.divides(mono, b));
-      ASSERT_FALSE(m.divides(m, mono, b));
-
-      ASSERT_FALSE(m.isProductOf(a, c, b));
-      ASSERT_FALSE(m.isProductOfHintTrue(a, c, b));
-      ASSERT_FALSE(m.isTwoProductsOfHintTrue(c, c, a, b, b));
-      ASSERT_FALSE(m.isTwoProductsOfHintTrue(b, c, a, c, b));
-      ASSERT_FALSE(m.isTwoProductsOfHintTrue(c, b, a, b, c));
-    } else {
-      ASSERT_TRUE(m.equal(b, mono));
-      ASSERT_TRUE(m.compare(b, mono) == Monoid::EqualTo);
-      ASSERT_TRUE(m.divides(mono, b));
-      ASSERT_TRUE(m.divides(m, mono, b));
-    }
-
-    if (!m.isIdentity(b)) {
-      ASSERT_TRUE(m.lessThan(a, mono));
-      ASSERT_FALSE(m.lessThan(mono, a));
-      ASSERT_TRUE(m.compare(mono, a) == Monoid::GreaterThan);
-      ASSERT_FALSE(m.divides(mono, a));
-      ASSERT_FALSE(m.divides(m, mono, a));
-
-      ASSERT_FALSE(m.isProductOf(c, b, a));
-      ASSERT_FALSE(m.isProductOfHintTrue(b, c, a));
-      ASSERT_FALSE(m.isTwoProductsOfHintTrue(c, c, b, a, a));
-      ASSERT_FALSE(m.isTwoProductsOfHintTrue(a, c, b, c, a));
-      ASSERT_FALSE(m.isTwoProductsOfHintTrue(c, a, b, a, c));
-    } else {
-      ASSERT_TRUE(m.equal(a, mono));
-      ASSERT_TRUE(m.compare(a, mono) == Monoid::EqualTo);
-      ASSERT_TRUE(m.divides(m, mono, a));
-    }
-
-    // Check that aliased parameters work.
-    m.multiply(mono, mono, mono);
-    m.divide(mono, mono, mono);
-    MATHICGB_ASSERT(m.isIdentity(mono));
-
-    // Check that negative exponents work.
-    if (Monoid::HasComponent && m.component(a) != m.component(b))
-      return;
-    m.divideToNegative(a, b, mono);
-    m.multiply(a, mono, mono);
-    ASSERT_TRUE(m.equal(mono, b));
-    
-    m.divideToNegative(b, a, mono);
-    m.multiply(b, mono, mono);
-    ASSERT_TRUE(m.equal(mono, a));
-  };
-  check("1 1 1", false);
-  check("a<5> 1 a<5>", true);
-  check("1 Vx Vx", false);
-  check("aV bx abxV", false);
-  check("a a2 a3", false);
-  check("V<2> V2 V3<2>", true);
-  check("arlgh svug arlg2hsvu", false);
-  check("abcdefghiV<7> ab2c3d4e5f6g7h8i9V11 a2b3c4d5e6f7g8h9i10V12<7>", true);
-}
-
-TYPED_TEST(Monoid, LcmColon) {
-  typedef TypeParam Monoid;
-  Monoid mNonConst(49);
-  auto& m = mNonConst;
-  typename Monoid::MonoPool pool(m);
-  auto mono = pool.alloc();
-  auto mono2 = pool.alloc();
-  auto check = [&](const char* const str, const bool component) -> void {
-    if (component && !Monoid::HasComponent)
-      return;
-    auto v = parseVector(m, str);
-    MATHICGB_ASSERT(v.size() == 3);
-    const auto& a = v.front();
-    const auto& b = *++v.begin();
-    const auto& lcm = v.back();
-
-    // isLcm (+general)
-    ASSERT_TRUE(m.isLcm(a, b, lcm));
-    ASSERT_TRUE(m.isLcm(m, a, m, b, lcm));
-    m.copy(lcm, mono);
-    m.setExponent(1, m.exponent(mono, 1) + 1, mono);
-    ASSERT_FALSE(m.isLcm(a, b, mono));
-    ASSERT_FALSE(m.isLcm(m, a, m, b, mono));
-
-    // dividesLcm
-    ASSERT_TRUE(m.dividesLcm(lcm, a, b));
-    ASSERT_FALSE(m.dividesLcm(mono, a, b));
-    ASSERT_TRUE(m.dividesLcm(a, a, a));
-    ASSERT_TRUE(m.dividesLcm(a, a, b));
-    ASSERT_TRUE(m.dividesLcm(b, b, b));
-    ASSERT_TRUE(m.dividesLcm(b, b, a));
-
-    // dividesLcm, general
-    ASSERT_TRUE(m.dividesLcm(m, lcm, m, a, b));
-    ASSERT_FALSE(m.dividesLcm(m, mono, m, a, b));
-    ASSERT_TRUE(m.dividesLcm(m, a, m, a, a));
-    ASSERT_TRUE(m.dividesLcm(m, a, m, a, b));
-    ASSERT_TRUE(m.dividesLcm(m, b, m, b, b));
-    ASSERT_TRUE(m.dividesLcm(m, b, m, b, a));
-
-    // lcm(a, b)
-    m.lcm(a, b, mono);
-    ASSERT_TRUE(m.equal(mono, lcm));
-    ASSERT_TRUE(m.compare(mono, lcm) == Monoid::EqualTo);
-    ASSERT_EQ(m.hash(lcm), m.hash(mono));
-
-    // lcm(b, a), general
-    m.lcm(m, b, m, a, mono);
-    ASSERT_TRUE(m.equal(mono, lcm));
-    ASSERT_TRUE(m.compare(mono, lcm) == Monoid::EqualTo);
-    ASSERT_EQ(m.hash(lcm), m.hash(mono));
-
-    // colons
-    m.colons(a, b, mono, mono2);
-    m.multiply(b, mono, mono);
-    m.multiply(a, mono2, mono2);
-    ASSERT_TRUE(m.equal(mono, lcm));
-    ASSERT_TRUE(m.compare(mono, lcm) == Monoid::EqualTo);
-    ASSERT_TRUE(m.equal(mono2, lcm));
-    ASSERT_TRUE(m.compare(mono2, lcm) == Monoid::EqualTo);
-  };
-  check("1 1 1", false);
-  check("a<2> 1<2> a<2>", true);
-  check("1 Vx Vx", false);
-  check("aV bx abxV", false);
-  check("a a2 a2", false);
-  check("V<3> V2<3> V2<3>", true);
-  check("arlgh svug arlghsvu", false);
-  check("a6b7c8d9efghiV ab2c3d4e5f6g7h8i9V11 a6b7c8d9e5f6g7h8i9V11", false);
-}
-
-TYPED_TEST(Monoid, Order) {
-  typedef TypeParam Monoid;
-  typedef typename Monoid::Order Order;
-  typedef typename Monoid::Exponent Exponent;
-
-  auto check = [](const Monoid& m, const char* sorted) -> void {
-    auto v = parseVector(m, sorted);
-    for (auto greater = v.begin(); greater != v.end(); ++greater) {
-      ASSERT_EQ(m.compare(*greater, *greater), Monoid::EqualTo);
-      ASSERT_TRUE(m.equal(*greater, *greater));
-      ASSERT_FALSE(m.lessThan(*greater, *greater));
-      
-      for (auto lesser = v.begin(); lesser != greater; ++lesser) {
-        ASSERT_FALSE(m.equal(*lesser, *greater));
-        ASSERT_TRUE(m.lessThan(*lesser, *greater))
-          << "*lesser  is " << m.toString(*lesser) << '\n'
-          << "*greater is " << m.toString(*greater) << '\n';
-        ASSERT_FALSE(m.lessThan(*greater, *lesser));
-        ASSERT_EQ(m.compare(*lesser, *greater), Monoid::LessThan);
-        ASSERT_EQ(m.compare(*greater, *lesser), Monoid::GreaterThan);
-      }
-    }
-  };
-
-  const auto sortedTotalDegreeRevLex =
-    "1 Z A z c b a c2 bc ac b2 ab a2 c3 abc b3 a3";
-  check(Monoid(52), sortedTotalDegreeRevLex);
-  check(
-    Monoid(Order(52, std::vector<Exponent>(52, 1), Order::RevLexBaseOrder)),
-    sortedTotalDegreeRevLex
-  );
-  check(
-    Monoid(Order(52, std::vector<Exponent>(52, 7), Order::RevLexBaseOrder)),
-    sortedTotalDegreeRevLex
-  );
-  std::vector<Exponent> revLexGradings(52, 1);
-  for (size_t grading = 51; grading != static_cast<size_t>(-1); --grading)
-    for (size_t var = 0; var < 52; ++var)
-      revLexGradings.push_back(var == grading ? -1 : 0);
-  check(
-    Monoid(
-      Order(52, std::vector<Exponent>(revLexGradings), Order::RevLexBaseOrder)
-    ),
-    sortedTotalDegreeRevLex
-  );
-  check(
-    Monoid(Order(52, std::move(revLexGradings), Order::LexBaseOrder)),
-    sortedTotalDegreeRevLex
-  );
-
-  std::vector<Exponent> dupGradings = {
-     5, 2, 3,
-    10, 4, 6, // duplicate, just multiplied by 2
-    -6, 9, 4,
-    -6, 9, 4,
-    -6, 9, 4,
-    -6, 9, 4,
-    -6, 9, 4
-  };
-  //   b:  2  9
-  //   c:  3  4
-  //   a:  5 -7
-  //  bc:  5 20
-  //  c2:  6  8
-  //  b3:  6 27
-  // bc3: 11 21
-  // ab3: 11 21
-  const auto sortedDupGradingsRevLex = "1 b c a bc c2 b3 bc3 ab3";
-  check(
-    Monoid(Order(3, std::move(dupGradings), Order::RevLexBaseOrder)),
-    sortedDupGradingsRevLex
-  );
-
-  std::vector<Exponent> lexGradings = {
-    0, 0, 1,
-    0, 1, 0,
-    1, 0, 0
-  };
-  const auto sortedLex =
-    "1 a a2 a3 b ab a2b b2 ab2 b3 c ac bc abc c2 ac2 bc2 c3";
-  check(
-    Monoid(
-      Order(3, std::vector<Exponent>(lexGradings), Order::RevLexBaseOrder)
-    ),
-    sortedLex
-  );
-  check
-    (Monoid(Order(3, std::move(lexGradings), Order::LexBaseOrder)), sortedLex);
-  check
-    (Monoid(Order(3, std::vector<Exponent>(), Order::LexBaseOrder)), sortedLex);
-}
-
-TYPED_TEST(Monoid, RelativelyPrime) {
-  typedef TypeParam Monoid;
-  Monoid m(49);
-  typename Monoid::MonoPool pool(m);
-  auto mono = pool.alloc();
-  auto mono2 = pool.alloc();
-  auto check = [&](const char* str, bool relativelyPrime) -> void {
-    auto v = parseVector(m, str);
-    MATHICGB_ASSERT(v.size() == 2);
-    ASSERT_EQ(relativelyPrime, m.relativelyPrime(v.front(), v.back()));
-    ASSERT_EQ(relativelyPrime, m.relativelyPrime(v.back(), v.front()));
-  };
-  check("1 1", true);
-  check("1 abcdefgh", true);
-  check("abc defgh", true);
-  check("bdfh aceg", true);
-  check("bdefh aceg", false);
-  check("abcdefgh abcdefgh", false);
-  check("fgh abcdef", false);
-}
-
-TYPED_TEST(Monoid, SetExponents) {
-  typedef TypeParam Monoid;
-  Monoid m(5);
-  auto v = parseVector(m, "a1b2c3d4e5");
-  typename Monoid::Exponent exponents[] = {1, 2, 3, 4, 5};
-  v.push_back();
-  m.setExponents(exponents, v.back());
-  ASSERT_TRUE(m.equal(v.front(), v.back()));  
-}
-
-TYPED_TEST(Monoid, HasAmpleCapacityTotalDegree) {
-  typedef TypeParam Monoid;
-  typedef typename Monoid::Order Order;
-  typedef typename Monoid::Exponent Exponent;
-  typedef typename Monoid::VarIndex VarIndex;
-
-  for (VarIndex varCount = 1; varCount < 33; ++varCount) {
-    Monoid monoidTotalDegree(varCount);
-    
-    std::vector<Exponent> ones(varCount, 1);
-    Monoid monoidTotalDegreeImplicit
-      (Order(varCount, std::move(ones), Order::RevLexBaseOrder));
-
-    std::vector<Exponent> mostlyOnes(varCount, 1);
-    mostlyOnes[0] = 7;
-    Monoid monoidGeneral
-      (Order(varCount, std::move(mostlyOnes), Order::RevLexBaseOrder));
-
-    Monoid* monoids[] = {
-      &monoidTotalDegree,
-      &monoidTotalDegreeImplicit,
-      &monoidGeneral
-    };
-    for (int j = 0; j < 3; ++j) {
-      auto& m = *monoids[j];
-      const auto firstDeg = (j == 2 ? 7 : 1);
-      ASSERT_EQ(varCount, m.varCount());
-
-      typename Monoid::MonoPool p(m);
-      auto mono = p.alloc();
-      const auto last = m.varCount() - 1;
-      const auto max = std::numeric_limits<Exponent>::max() / 2;
-
-      // pure power, first variable
-      m.setIdentity(mono);
-      m.setExponent(0, max / firstDeg, mono);
-      ASSERT_TRUE(m.hasAmpleCapacity(mono));
-      m.setExponent(0, max / firstDeg + 1, mono);
-      ASSERT_FALSE(m.hasAmpleCapacity(mono));
-
-      if (varCount == 1)
-        continue;
-
-      // pure power, last variable
-      m.setIdentity(mono);
-      m.setExponent(last, max, mono);
-      ASSERT_TRUE(m.hasAmpleCapacity(mono));
-      m.setExponent(last, max + 1, mono);
-      ASSERT_FALSE(m.hasAmpleCapacity(mono));
-
-      // no exponent is too high but the degree is
-      m.setIdentity(mono);
-      m.setExponent(0, 12, mono);
-      m.setExponent(last, max - 12 * firstDeg, mono);
-      ASSERT_TRUE(m.hasAmpleCapacity(mono));
-      m.setExponent(0, 13, mono);
-      ASSERT_FALSE(m.hasAmpleCapacity(mono));
-    }
-  }
-}
-
-TYPED_TEST(Monoid, CopyEqualConversion) {
-  typedef TypeParam Monoid;
-  typedef typename Monoid::Order Order;
-  typedef typename Monoid::Exponent Exponent;
-  typedef typename Monoid::VarIndex VarIndex;
-  static const bool HasComponent = Monoid::HasComponent;
-  typedef MonoMonoid<Exponent, HasComponent, false, false> MonoidNone;
-  typedef MonoMonoid<Exponent, HasComponent, true, true> MonoidAll;
-  for (VarIndex varCount = 1; varCount < 33; ++varCount) {
-    const Order order
-      (varCount, std::vector<Exponent>(varCount, 1), Order::RevLexBaseOrder);
-    MonoidNone none(order);
-    Monoid some(Monoid::create(none));
-    MonoidAll all(MonoidAll::create(some));
-
-    auto none1 = none.alloc();
-    auto none2 = none.alloc();
-    auto none3 = none.alloc();
-    auto some1 = some.alloc();
-    auto some2 = some.alloc();
-    auto some3 = some.alloc();
-    auto all1 = all.alloc();
-    auto all2 = all.alloc();
-    auto all3 = all.alloc();
-
-    none.setExponent(0, 1, none1);
-    none.setExponent(varCount / 2, 2, none1);
-    none.setExponent(varCount - 1, 3, none1);
-    none.copy(none1, none2);
-    none.setExponent(0, 4, none2);
-
-    some.setExponent(0, 1, some1);
-    some.setExponent(varCount / 2, 2, some1);
-    some.setExponent(varCount - 1, 3, some1);
-    some.copy(some1, some2);
-    some.setExponent(0, 4, some2);
-
-    all.setExponent(0, 1, all1);
-    all.setExponent(varCount / 2, 2, all1);
-    all.setExponent(varCount - 1, 3, all1);
-    all.copy(all1, all2);
-    all.setExponent(0, 4, all2);
-
-    // compare on none
-    ASSERT_TRUE(none.equal(none, none1, none1));
-    ASSERT_TRUE(none.equal(some, some1, none1));
-    ASSERT_TRUE(none.equal(all, all1, none1));
-    ASSERT_FALSE(none.equal(none, none1, none2));
-    ASSERT_FALSE(none.equal(some, some1, none2));
-    ASSERT_FALSE(none.equal(all, all1, none2));
-
-    // compare on some
-    ASSERT_TRUE(some.equal(none, none1, some1));
-    ASSERT_TRUE(some.equal(some, some1, some1));
-    ASSERT_TRUE(some.equal(all, all1, some1));
-    ASSERT_FALSE(some.equal(none, none1, some2));
-    ASSERT_FALSE(some.equal(some, some1, some2));
-    ASSERT_FALSE(some.equal(all, all1, some2));
-
-    // compare on all
-    ASSERT_TRUE(all.equal(none, none1, all1));
-    ASSERT_TRUE(all.equal(some, some1, all1));
-    ASSERT_TRUE(all.equal(all, all1, all1));
-    ASSERT_FALSE(all.equal(none, none1, all2));
-    ASSERT_FALSE(all.equal(some, some1, all2));
-    ASSERT_FALSE(all.equal(all, all1, all2));
-
-    // convert some->none
-    none.copy(some, some1, none3);
-    ASSERT_TRUE(none.equal(none1, none3));
-    ASSERT_FALSE(none.equal(none2, none3));
-    none.copy(some, some2, none3);
-    ASSERT_FALSE(none.equal(none1, none3));
-    ASSERT_TRUE(none.equal(none2, none3));
-
-    /// convert some->all
-    all.copy(some, some1, all3);
-    ASSERT_TRUE(all.equal(all1, all3));
-    ASSERT_FALSE(all.equal(all2, all3));
-    all.copy(some, some2, all3);
-    ASSERT_FALSE(all.equal(all1, all3));
-    ASSERT_TRUE(all.equal(all2, all3));
-
-    // convert none->some
-    some.copy(none, none1, some3);
-    ASSERT_TRUE(some.equal(some1, some3));
-    ASSERT_FALSE(some.equal(some2, some3));
-    some.copy(none, none2, some3);
-    ASSERT_FALSE(some.equal(some1, some3));
-    ASSERT_TRUE(some.equal(some2, some3));
-
-    // convert Y->some
-    some.copy(none, none1, some3);
-    ASSERT_TRUE(some.equal(some1, some3));
-    ASSERT_FALSE(some.equal(some2, some3));
-    some.copy(none, none2, some3);
-    ASSERT_FALSE(some.equal(some1, some3));
-    ASSERT_TRUE(some.equal(some2, some3));
-  }
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+#include "mathicgb/MonoMonoid.hpp"
+
+#include <gtest/gtest.h>
+#include <sstream>
+
+using namespace mgb;
+
+// Do all-pairs testing -- see monoidPict.in. Especially see that file before
+// editing this list of types.
+typedef ::testing::Types<
+  MonoMonoid<int32,1,1,1>,
+  MonoMonoid<int32,0,1,1>,
+  MonoMonoid<int32,0,0,1>,
+  MonoMonoid<int32,0,0,0>,
+  MonoMonoid<int16,1,1,1>,
+  MonoMonoid<int16,0,1,1>,
+  MonoMonoid<int16,0,0,1>,
+  MonoMonoid<int16,0,0,0>,
+  MonoMonoid<int8,1,0,1>,
+  MonoMonoid<int8,0,1,0>,
+  MonoMonoid<int32,1,1,0>
+> MonoidTypes;
+
+template <typename T>
+class Monoid : public ::testing::Test {};
+TYPED_TEST_CASE(Monoid, MonoidTypes);
+
+// expect(i,j) encodes a matrix with interesting bit patterns that
+// are supposed to be likely to surface errors in how monomials are
+// stored inside a vector.
+uint32 expect(size_t mono, size_t var, size_t varCount) {
+  const auto unique = (static_cast<uint32>(var + varCount * mono + 1) % 127);
+
+  while (true) {
+    // 000
+    if (mono == 0)
+      return 0;
+    --mono;
+
+    // 100
+    // 010
+    // 001
+    if (mono < varCount)
+      return var == mono ? unique : 0;
+    mono -= varCount;
+
+    // 000
+    // 100
+    // 110
+    // 111
+    if (mono < varCount + 1)
+      return var < mono ? unique : 0;
+    mono -= varCount + 1;
+
+    // 111
+    // 011
+    // 001
+    // 000
+    if (mono < varCount + 1)
+      return var >= mono ? unique : 0;
+    mono -= varCount + 1;
+
+    // 101
+    // 010
+    if (mono < 4)
+      return (var % 2) == (mono % 2) ? unique : 0;
+    mono -= 4;
+
+    // 100100
+    // 010010
+    // 001001
+    if (mono < 6)
+      return (var % 3) == (mono % 3) ? unique : 0;
+    mono -= 6;
+
+    // mix the patterns
+    mono += var % 17;
+  }
+};
+
+TYPED_TEST(Monoid, VarCount) {
+  typedef TypeParam Monoid;
+  ASSERT_EQ(0, Monoid(0).varCount());
+  ASSERT_EQ(1000 * 1000, Monoid(1000 * 1000).varCount());
+  ASSERT_EQ(1, Monoid(1).varCount());
+  ASSERT_EQ(2, Monoid(2).varCount());
+  ASSERT_EQ(12, Monoid(12).varCount());
+}
+
+TYPED_TEST(Monoid, MonoVector) {
+  typedef TypeParam Monoid;
+  typedef typename Monoid::VarIndex VarIndex;
+  typedef typename Monoid::MonoVector MonoVector;
+
+  Monoid monoid(13);
+  MonoVector v(monoid);
+  MonoVector v2(monoid);
+  ASSERT_EQ(v2.monoid(), monoid);
+  const auto varCount = monoid.varCount();
+
+  ASSERT_TRUE(v.empty());
+  size_t count = 1000;
+
+
+  // Not a correctness error, but empty vectors should preferably not
+  // use any memory.
+  ASSERT_EQ(0, v.memoryBytesUsed());
+
+  for (size_t i = 0; i < count; ++i) {
+    ASSERT_EQ(i, v.size());
+    v.push_back(); // push_back, no param
+    ASSERT_GT(v.memoryBytesUsed(), 0);
+    ASSERT_FALSE(v.empty()); // empty
+    ASSERT_EQ(i + 1, v.size()); // size
+
+
+    ASSERT_TRUE(monoid.isIdentity(v.back())); // isIdentity true, back non-const
+    bool allZero = true;
+    for (VarIndex var = 0; var < varCount; ++var) {
+      const auto exponent = expect(i, var, varCount);
+      if (exponent != 0) {
+	allZero = false;
+	monoid.setExponent(var, exponent, v.back());
+      }
+    }
+    ASSERT_EQ(allZero, monoid.isIdentity(v.back())); // isIdentity false
+    v2.push_back(v.back()); // push_back with param
+    ASSERT_TRUE(monoid.equal(v.back(), v2.back()));
+  }
+  auto it = v.begin();
+  ASSERT_EQ(it, v.cbegin());
+  for (size_t i = 0; i < count; ++i, ++it) {
+    typename MonoVector::const_iterator tmp;
+    tmp = it;
+    ASSERT_EQ(tmp, it);
+    ASSERT_TRUE(v.end() != it);
+
+    for (VarIndex var = 0; var < monoid.varCount(); ++var) {
+      ASSERT_EQ(expect(i, var, varCount), monoid.exponent(*it, var));
+    }
+  }
+  ASSERT_EQ(v.end(), it);
+  ASSERT_EQ(v.cend(), it);
+
+  ASSERT_EQ(v, v2); // operator== true
+  monoid.setExponent(0, 1 + monoid.exponent(v2.back(), 0), v2.back());
+  ASSERT_TRUE(v != v2); // operator!=, true, same length
+
+  auto& vc = const_cast<const MonoVector&>(v);
+  ASSERT_TRUE(monoid.equal(v.front(), *v2.begin())); // front, non-const
+  ASSERT_TRUE(monoid.equal(vc.front(), *v2.begin())); // front, const
+  ASSERT_TRUE(monoid.equal(vc.back(), v.back())); // back, non-const
+
+  auto v3(v2); // copy constructor
+  ASSERT_EQ(v3.monoid(), monoid);
+  ASSERT_TRUE(v != v3 && v2 == v3);
+  v2.swap(v); // member swap
+  ASSERT_TRUE(v == v3 && v2 != v3);
+  std::swap(v, v2); // std::swap
+  ASSERT_TRUE(v != v3 && v2 == v3);
+  using std::swap;
+  swap(v, v2); // let compiler decide which swap to use
+  ASSERT_TRUE(v == v3 && v2 != v3);
+  swap(v, v2); // get back to original state
+  ASSERT_TRUE(v != v3 && v2 == v3);
+
+  ASSERT_FALSE(v3 != v2); // operator!=, false, same length
+  v3.push_back();
+  ASSERT_TRUE(v3 != v2); // operator!=, true, different length
+  
+
+  ASSERT_FALSE(v3 == v);
+  v3 = v; // copy assignment
+  ASSERT_EQ(v3.monoid(), monoid);
+  ASSERT_EQ(v3, v);
+
+  ASSERT_FALSE(v3.empty());
+  v2 = std::move(v3); // move assignment
+  ASSERT_EQ(v2.monoid(), monoid);
+  ASSERT_EQ(v2, v);
+  ASSERT_TRUE(v3.empty());
+
+  ASSERT_FALSE(v2.empty());
+  auto v4(std::move(v2)); // move constructor
+  ASSERT_EQ(v4.monoid(), monoid);
+  ASSERT_TRUE(v2.empty());
+  ASSERT_EQ(v4, v);
+
+  ASSERT_FALSE(v.empty());
+  v.clear();
+  ASSERT_TRUE(v.empty());
+}
+
+TYPED_TEST(Monoid, ReadWriteMonoid) {
+  typedef TypeParam Monoid;
+  typedef typename Monoid::VarIndex VarIndex;
+
+  const auto check = [](
+    const char* const inStr,
+    const char* const outStr,
+    const VarIndex varCount,
+    const VarIndex gradingCount
+    ) -> void {
+    for (int i = 0; i < 2; ++i) {
+      const char* str = i == 0 ? inStr : outStr;
+      if (str == 0)
+        continue;
+
+      std::istringstream in(str);
+      const auto p = Monoid::readMonoid(in);
+      const auto& m = p.first;
+
+      std::ostringstream out;
+      m.printMonoid(p.second.first, out);
+      ASSERT_EQ(outStr, out.str());
+      ASSERT_EQ(varCount, m.varCount());
+      ASSERT_EQ(gradingCount, m.gradingCount());
+    }
+  };
+  check("0 0\n", "0\nrevlex 0\n", 0, 0);
+  check("1 1\n 2\n", "1\nrevlex 1\n 2\n", 1, 1);
+  check("1 2\n 3\n 4\n", "1\nrevlex 2\n 3\n 4\n", 1, 2);
+  check("2 2\n 3 4\n 5 6\n", "2\nrevlex 2\n 3 4\n 5 6\n", 2, 2);
+  check("4 1\n 1 1 1 1\n", "4\nrevlex 1\n 1 1 1 1\n", 4, 1);
+
+  check("0 lex 0", "0\nlex 0\n", 0, 0);
+  check("1 lex 1 2", "1\nlex 1\n 2\n", 1, 1);
+  check("1 lex 2 3 4", "1\nlex 2\n 3\n 4\n", 1, 2);
+  check("2 lex 2 3 4 5 6", "2\nlex 2\n 3 4\n 5 6\n", 2, 2);
+  check("4 lex 1 1 1 1 1", "4\nlex 1\n 1 1 1 1\n", 4, 1);
+
+  if (Monoid::HasComponent) {
+    check("2 2\n component\n 5 6\n", "2\nrevlex 2\n component\n 5 6\n", 2, 2);
+    check
+      ("2 2\n 3 4\n revcomponent\n","2\nrevlex 2\n 3 4\n revcomponent\n", 2, 2);
+    check("0 lex 1 component", "0\nlex 0\n", 0, 0);
+    check("1 lex 1 revcomponent", "1\nlex 1\n revcomponent\n", 1, 1);
+    check("5 lex 1 revcomponent", "5\nlex 1\n revcomponent\n", 5, 1);
+  }
+}
+
+TYPED_TEST(Monoid, MonoPool) {
+  typedef TypeParam Monoid;
+  typedef typename Monoid::VarIndex VarIndex;
+  typedef typename Monoid::Mono Mono;
+
+  for (int q = 0; q < 2; ++q) {
+    Monoid monoid(13);
+    typename Monoid::MonoPool pool(monoid);
+    const auto varCount = monoid.varCount();
+
+    const auto count = 1000;
+    std::vector<Mono> monos;
+    for (int i = 0; i < count; ++i) {
+      pool.alloc();
+      pool.free(pool.alloc());
+      auto m1 = pool.alloc();
+      ASSERT_TRUE(monoid.isIdentity(m1));
+      auto m2 = pool.alloc();
+      ASSERT_TRUE(monoid.isIdentity(m2));
+      for (VarIndex var = 0; var < varCount; ++var) {
+        monoid.setExponent(var, 1, m1);
+        monoid.setExponent(var, 1, m2);
+      }
+      if (i > 10) {
+        using std::swap;
+        swap(m2, monos[i - 10]);
+      }
+      monos.emplace_back(std::move(m1));
+    }
+    
+    // This ensures that we get to each entry in monos exactly once.
+    MATHICGB_ASSERT((count % 17) != 0); 
+    int i = 0;
+    do {
+      MATHICGB_ASSERT(!monos[i].isNull());
+      ASSERT_FALSE(monoid.isIdentity(monos[i]));
+      pool.free(std::move(monos[i]));
+      ASSERT_TRUE(monos[i].isNull());
+      pool.free(std::move(monos[i]));
+      ASSERT_TRUE(monos[i].isNull());
+      i = (i + 17) % count;
+    } while (i != 0);
+
+    // If the ordering of monomials inside the pool has anything to do with
+    // allocation and deallocation order, then the monomials inside the
+    // pool are at this point all jumbled around. All the entries were also
+    // non-zero before, so we test that new allocations are the identity.
+
+    for (int i = 0; i < count; ++i) {
+      monos[i] = pool.alloc();
+      ASSERT_TRUE(monoid.isIdentity(monos[i]));
+      for (VarIndex var = 0; var < varCount; ++var)
+        monoid.setExponent(var, expect(i, var, varCount), monos[i]);
+    }
+    for (int i = 0; i < count; ++i) {
+      for (VarIndex var = 0; var < varCount; ++var) {
+        ASSERT_EQ(expect(i, var, varCount), monoid.exponent(monos[i], var));
+      }
+    }
+    // everything should be free'd now. Let's do all that again.
+  }
+}
+
+namespace {
+  template<class M>
+  typename M::MonoVector parseVector(M& monoid, const char* str) {
+    typename M::MonoVector v(monoid);
+    std::istringstream in(str);
+    v.parseM2(in);
+    return v;
+  }
+}
+
+TYPED_TEST(Monoid, ParsePrintM2) {
+  typedef TypeParam Monoid;
+  Monoid m(100);
+  std::string str = "1 a z A Z ab a2 a2b ab2 a20b30";
+  if (Monoid::HasComponent)
+    str += " 1<1> a<2> a2<3> ab<11>\n";
+  else
+    str += '\n';
+  auto v2 = parseVector(m, str.c_str());
+  std::ostringstream v2Out;
+  v2.printM2(v2Out);
+  ASSERT_EQ(str, v2Out.str());
+
+  decltype(v2) v(m);
+  v.push_back(); // 1
+
+  v.push_back(); // a
+  m.setExponent(0, 1, v.back());
+ 
+  v.push_back(); // z
+  m.setExponent(25, 1, v.back());
+
+  v.push_back(); // A
+  m.setExponent(26, 1, v.back());
+
+  v.push_back(); // Z
+  m.setExponent(51, 1, v.back());
+
+  v.push_back(); // ab
+  m.setExponent(0, 1, v.back());
+  m.setExponent(1, 1, v.back());
+
+  v.push_back(); // a2
+  m.setExponent(0, 2, v.back());
+
+  v.push_back(); // a2b
+  m.setExponent(0, 2, v.back());
+  m.setExponent(1, 1, v.back());
+
+  v.push_back(); // ab2
+  m.setExponent(0, 1, v.back());
+  m.setExponent(1, 2, v.back());
+
+  v.push_back(); // a20b30
+  m.setExponent(0, 20, v.back());
+  m.setExponent(1, 30, v.back());
+
+  if (Monoid::HasComponent) {
+    v.push_back(); // 1<1>
+    m.setComponent(1, v.back());
+
+    v.push_back(); // a<2>
+    m.setComponent(2, v.back());
+    m.setExponent(0, 1, v.back());
+
+    v.push_back(); // a2<3>
+    m.setComponent(3, v.back());
+    m.setExponent(0, 2, v.back());
+
+    v.push_back(); // ab<11>
+    m.setComponent(11, v.back());
+    m.setExponent(0, 1, v.back());
+    m.setExponent(1, 1, v.back());
+  }
+
+  std::ostringstream vOut;
+  v.printM2(vOut);
+  ASSERT_EQ(str, vOut.str());
+  
+  ASSERT_EQ(v, v2);
+}
+
+
+TYPED_TEST(Monoid, MultiplyDivide) {
+  typedef TypeParam Monoid;
+  Monoid m(49);
+  typename Monoid::MonoPool pool(m);
+  auto mono = pool.alloc();
+  auto check = [&](const char* const str, const bool component) -> void {
+    if (component && !Monoid::HasComponent)
+      return;
+    auto v = parseVector(m, str);
+    MATHICGB_ASSERT(v.size() == 3);
+    const auto& a = v.front();
+    const auto& b = *++v.begin();
+    const auto& c = v.back();
+    ASSERT_EQ(m.hashOfProduct(a, b), m.hash(c));
+    ASSERT_EQ(m.hashOfProduct(a, b), m.hashOfProduct(b, a));
+
+    // isProductOf
+    ASSERT_TRUE(m.isProductOf(a, b, c));
+    ASSERT_TRUE(m.isProductOfHintTrue(a, b, c));
+    ASSERT_TRUE(m.isTwoProductsOfHintTrue(a, a, b, c, c));
+    
+
+    // a*b == c using multiply
+    m.multiply(a, b, mono);
+    ASSERT_TRUE(m.equal(c, mono));
+    ASSERT_TRUE(m.compare(c, mono) == Monoid::EqualTo);
+    ASSERT_EQ(m.hash(c), m.hash(mono));
+
+    // c/a == b using divide
+    m.divide(a, c, mono);
+    ASSERT_TRUE(m.equal(b, mono));
+    ASSERT_TRUE(m.compare(b, mono) == Monoid::EqualTo);
+    ASSERT_EQ(m.hash(b), m.hash(mono));
+
+    // c/b == a using divideInPlace
+    m.copy(c, mono);
+    m.divideInPlace(b, mono);
+    ASSERT_TRUE(m.equal(a, mono));
+    ASSERT_TRUE(m.compare(a, mono) == Monoid::EqualTo);
+    ASSERT_EQ(m.hash(a), m.hash(mono));
+
+    // a*b == c using multiplyInPlace
+    m.copy(a, mono);
+    m.multiplyInPlace(b, mono);
+    ASSERT_TRUE(m.equal(c, mono));
+    ASSERT_TRUE(m.compare(c, mono) == Monoid::EqualTo);
+    ASSERT_EQ(m.hash(c), m.hash(mono));
+
+    // divides, check properties that mono=a*b should have
+    ASSERT_TRUE(m.divides(mono, c));
+    ASSERT_TRUE(m.divides(c, mono));
+    ASSERT_TRUE(m.divides(a, mono));
+    ASSERT_TRUE(m.divides(b, mono));
+
+    // divides, general
+    ASSERT_TRUE(m.divides(m, mono, c));
+    ASSERT_TRUE(m.divides(m, c, mono));
+    ASSERT_TRUE(m.divides(m, a, mono));
+    ASSERT_TRUE(m.divides(m, b, mono));
+
+    if (!m.isIdentity(a)) {
+      ASSERT_TRUE(m.lessThan(b, mono));
+      ASSERT_FALSE(m.lessThan(mono, b));
+      ASSERT_TRUE(m.compare(mono, b) == Monoid::GreaterThan);
+      ASSERT_FALSE(m.divides(mono, b));
+      ASSERT_FALSE(m.divides(m, mono, b));
+
+      ASSERT_FALSE(m.isProductOf(a, c, b));
+      ASSERT_FALSE(m.isProductOfHintTrue(a, c, b));
+      ASSERT_FALSE(m.isTwoProductsOfHintTrue(c, c, a, b, b));
+      ASSERT_FALSE(m.isTwoProductsOfHintTrue(b, c, a, c, b));
+      ASSERT_FALSE(m.isTwoProductsOfHintTrue(c, b, a, b, c));
+    } else {
+      ASSERT_TRUE(m.equal(b, mono));
+      ASSERT_TRUE(m.compare(b, mono) == Monoid::EqualTo);
+      ASSERT_TRUE(m.divides(mono, b));
+      ASSERT_TRUE(m.divides(m, mono, b));
+    }
+
+    if (!m.isIdentity(b)) {
+      ASSERT_TRUE(m.lessThan(a, mono));
+      ASSERT_FALSE(m.lessThan(mono, a));
+      ASSERT_TRUE(m.compare(mono, a) == Monoid::GreaterThan);
+      ASSERT_FALSE(m.divides(mono, a));
+      ASSERT_FALSE(m.divides(m, mono, a));
+
+      ASSERT_FALSE(m.isProductOf(c, b, a));
+      ASSERT_FALSE(m.isProductOfHintTrue(b, c, a));
+      ASSERT_FALSE(m.isTwoProductsOfHintTrue(c, c, b, a, a));
+      ASSERT_FALSE(m.isTwoProductsOfHintTrue(a, c, b, c, a));
+      ASSERT_FALSE(m.isTwoProductsOfHintTrue(c, a, b, a, c));
+    } else {
+      ASSERT_TRUE(m.equal(a, mono));
+      ASSERT_TRUE(m.compare(a, mono) == Monoid::EqualTo);
+      ASSERT_TRUE(m.divides(m, mono, a));
+    }
+
+    // Check that aliased parameters work.
+    m.multiply(mono, mono, mono);
+    m.divide(mono, mono, mono);
+    MATHICGB_ASSERT(m.isIdentity(mono));
+
+    // Check that negative exponents work.
+    if (Monoid::HasComponent && m.component(a) != m.component(b))
+      return;
+    m.divideToNegative(a, b, mono);
+    m.multiply(a, mono, mono);
+    ASSERT_TRUE(m.equal(mono, b));
+    
+    m.divideToNegative(b, a, mono);
+    m.multiply(b, mono, mono);
+    ASSERT_TRUE(m.equal(mono, a));
+  };
+  check("1 1 1", false);
+  check("a<5> 1 a<5>", true);
+  check("1 Vx Vx", false);
+  check("aV bx abxV", false);
+  check("a a2 a3", false);
+  check("V<2> V2 V3<2>", true);
+  check("arlgh svug arlg2hsvu", false);
+  check("abcdefghiV<7> ab2c3d4e5f6g7h8i9V11 a2b3c4d5e6f7g8h9i10V12<7>", true);
+}
+
+TYPED_TEST(Monoid, LcmColon) {
+  typedef TypeParam Monoid;
+  Monoid mNonConst(49);
+  auto& m = mNonConst;
+  typename Monoid::MonoPool pool(m);
+  auto mono = pool.alloc();
+  auto mono2 = pool.alloc();
+  auto check = [&](const char* const str, const bool component) -> void {
+    if (component && !Monoid::HasComponent)
+      return;
+    auto v = parseVector(m, str);
+    MATHICGB_ASSERT(v.size() == 3);
+    const auto& a = v.front();
+    const auto& b = *++v.begin();
+    const auto& lcm = v.back();
+
+    // isLcm (+general)
+    ASSERT_TRUE(m.isLcm(a, b, lcm));
+    ASSERT_TRUE(m.isLcm(m, a, m, b, lcm));
+    m.copy(lcm, mono);
+    m.setExponent(1, m.exponent(mono, 1) + 1, mono);
+    ASSERT_FALSE(m.isLcm(a, b, mono));
+    ASSERT_FALSE(m.isLcm(m, a, m, b, mono));
+
+    // dividesLcm
+    ASSERT_TRUE(m.dividesLcm(lcm, a, b));
+    ASSERT_FALSE(m.dividesLcm(mono, a, b));
+    ASSERT_TRUE(m.dividesLcm(a, a, a));
+    ASSERT_TRUE(m.dividesLcm(a, a, b));
+    ASSERT_TRUE(m.dividesLcm(b, b, b));
+    ASSERT_TRUE(m.dividesLcm(b, b, a));
+
+    // dividesLcm, general
+    ASSERT_TRUE(m.dividesLcm(m, lcm, m, a, b));
+    ASSERT_FALSE(m.dividesLcm(m, mono, m, a, b));
+    ASSERT_TRUE(m.dividesLcm(m, a, m, a, a));
+    ASSERT_TRUE(m.dividesLcm(m, a, m, a, b));
+    ASSERT_TRUE(m.dividesLcm(m, b, m, b, b));
+    ASSERT_TRUE(m.dividesLcm(m, b, m, b, a));
+
+    // lcm(a, b)
+    m.lcm(a, b, mono);
+    ASSERT_TRUE(m.equal(mono, lcm));
+    ASSERT_TRUE(m.compare(mono, lcm) == Monoid::EqualTo);
+    ASSERT_EQ(m.hash(lcm), m.hash(mono));
+
+    // lcm(b, a), general
+    m.lcm(m, b, m, a, mono);
+    ASSERT_TRUE(m.equal(mono, lcm));
+    ASSERT_TRUE(m.compare(mono, lcm) == Monoid::EqualTo);
+    ASSERT_EQ(m.hash(lcm), m.hash(mono));
+
+    // colons
+    m.colons(a, b, mono, mono2);
+    m.multiply(b, mono, mono);
+    m.multiply(a, mono2, mono2);
+    ASSERT_TRUE(m.equal(mono, lcm));
+    ASSERT_TRUE(m.compare(mono, lcm) == Monoid::EqualTo);
+    ASSERT_TRUE(m.equal(mono2, lcm));
+    ASSERT_TRUE(m.compare(mono2, lcm) == Monoid::EqualTo);
+  };
+  check("1 1 1", false);
+  check("a<2> 1<2> a<2>", true);
+  check("1 Vx Vx", false);
+  check("aV bx abxV", false);
+  check("a a2 a2", false);
+  check("V<3> V2<3> V2<3>", true);
+  check("arlgh svug arlghsvu", false);
+  check("a6b7c8d9efghiV ab2c3d4e5f6g7h8i9V11 a6b7c8d9e5f6g7h8i9V11", false);
+}
+
+TYPED_TEST(Monoid, Order) {
+  typedef TypeParam Monoid;
+  typedef typename Monoid::Order Order;
+  typedef typename Monoid::Exponent Exponent;
+
+  auto check = [](const Monoid& m, const char* sorted) -> void {
+    auto v = parseVector(m, sorted);
+    for (auto greater = v.begin(); greater != v.end(); ++greater) {
+      ASSERT_EQ(m.compare(*greater, *greater), Monoid::EqualTo);
+      ASSERT_TRUE(m.equal(*greater, *greater));
+      ASSERT_FALSE(m.lessThan(*greater, *greater));
+      
+      for (auto lesser = v.begin(); lesser != greater; ++lesser) {
+        ASSERT_FALSE(m.equal(*lesser, *greater));
+        ASSERT_TRUE(m.lessThan(*lesser, *greater))
+          << "*lesser  is " << m.toString(*lesser) << '\n'
+          << "*greater is " << m.toString(*greater) << '\n';
+        ASSERT_FALSE(m.lessThan(*greater, *lesser));
+        ASSERT_EQ(m.compare(*lesser, *greater), Monoid::LessThan);
+        ASSERT_EQ(m.compare(*greater, *lesser), Monoid::GreaterThan);
+      }
+    }
+  };
+
+  const auto sortedTotalDegreeRevLex =
+    "1 Z A z c b a c2 bc ac b2 ab a2 c3 abc b3 a3";
+  check(Monoid(52), sortedTotalDegreeRevLex);
+  check(
+    Monoid(Order(52, std::vector<Exponent>(52, 1), Order::RevLexBaseOrder)),
+    sortedTotalDegreeRevLex
+  );
+  check(
+    Monoid(Order(52, std::vector<Exponent>(52, 7), Order::RevLexBaseOrder)),
+    sortedTotalDegreeRevLex
+  );
+  std::vector<Exponent> revLexGradings(52, 1);
+  for (size_t grading = 51; grading != static_cast<size_t>(-1); --grading)
+    for (size_t var = 0; var < 52; ++var)
+      revLexGradings.push_back(var == grading ? -1 : 0);
+  check(
+    Monoid(
+      Order(52, std::vector<Exponent>(revLexGradings), Order::RevLexBaseOrder)
+    ),
+    sortedTotalDegreeRevLex
+  );
+  check(
+    Monoid(Order(52, std::move(revLexGradings), Order::LexBaseOrder)),
+    sortedTotalDegreeRevLex
+  );
+
+  std::vector<Exponent> dupGradings = {
+     5, 2, 3,
+    10, 4, 6, // duplicate, just multiplied by 2
+    -6, 9, 4,
+    -6, 9, 4,
+    -6, 9, 4,
+    -6, 9, 4,
+    -6, 9, 4
+  };
+  //   b:  2  9
+  //   c:  3  4
+  //   a:  5 -7
+  //  bc:  5 20
+  //  c2:  6  8
+  //  b3:  6 27
+  // bc3: 11 21
+  // ab3: 11 21
+  const auto sortedDupGradingsRevLex = "1 b c a bc c2 b3 bc3 ab3";
+  check(
+    Monoid(Order(3, std::move(dupGradings), Order::RevLexBaseOrder)),
+    sortedDupGradingsRevLex
+  );
+
+  std::vector<Exponent> lexGradings = {
+    0, 0, 1,
+    0, 1, 0,
+    1, 0, 0
+  };
+  const auto sortedLex =
+    "1 a a2 a3 b ab a2b b2 ab2 b3 c ac bc abc c2 ac2 bc2 c3";
+  check(
+    Monoid(
+      Order(3, std::vector<Exponent>(lexGradings), Order::RevLexBaseOrder)
+    ),
+    sortedLex
+  );
+  check
+    (Monoid(Order(3, std::move(lexGradings), Order::LexBaseOrder)), sortedLex);
+  check
+    (Monoid(Order(3, std::vector<Exponent>(), Order::LexBaseOrder)), sortedLex);
+}
+
+TYPED_TEST(Monoid, RelativelyPrime) {
+  typedef TypeParam Monoid;
+  Monoid m(49);
+  typename Monoid::MonoPool pool(m);
+  auto mono = pool.alloc();
+  auto mono2 = pool.alloc();
+  auto check = [&](const char* str, bool relativelyPrime) -> void {
+    auto v = parseVector(m, str);
+    MATHICGB_ASSERT(v.size() == 2);
+    ASSERT_EQ(relativelyPrime, m.relativelyPrime(v.front(), v.back()));
+    ASSERT_EQ(relativelyPrime, m.relativelyPrime(v.back(), v.front()));
+  };
+  check("1 1", true);
+  check("1 abcdefgh", true);
+  check("abc defgh", true);
+  check("bdfh aceg", true);
+  check("bdefh aceg", false);
+  check("abcdefgh abcdefgh", false);
+  check("fgh abcdef", false);
+}
+
+TYPED_TEST(Monoid, SetExponents) {
+  typedef TypeParam Monoid;
+  Monoid m(5);
+  auto v = parseVector(m, "a1b2c3d4e5");
+  typename Monoid::Exponent exponents[] = {1, 2, 3, 4, 5};
+  v.push_back();
+  m.setExponents(exponents, v.back());
+  ASSERT_TRUE(m.equal(v.front(), v.back()));  
+}
+
+TYPED_TEST(Monoid, HasAmpleCapacityTotalDegree) {
+  typedef TypeParam Monoid;
+  typedef typename Monoid::Order Order;
+  typedef typename Monoid::Exponent Exponent;
+  typedef typename Monoid::VarIndex VarIndex;
+
+  for (VarIndex varCount = 1; varCount < 33; ++varCount) {
+    Monoid monoidTotalDegree(varCount);
+    
+    std::vector<Exponent> ones(varCount, 1);
+    Monoid monoidTotalDegreeImplicit
+      (Order(varCount, std::move(ones), Order::RevLexBaseOrder));
+
+    std::vector<Exponent> mostlyOnes(varCount, 1);
+    mostlyOnes[0] = 7;
+    Monoid monoidGeneral
+      (Order(varCount, std::move(mostlyOnes), Order::RevLexBaseOrder));
+
+    Monoid* monoids[] = {
+      &monoidTotalDegree,
+      &monoidTotalDegreeImplicit,
+      &monoidGeneral
+    };
+    for (int j = 0; j < 3; ++j) {
+      auto& m = *monoids[j];
+      const auto firstDeg = (j == 2 ? 7 : 1);
+      ASSERT_EQ(varCount, m.varCount());
+
+      typename Monoid::MonoPool p(m);
+      auto mono = p.alloc();
+      const auto last = m.varCount() - 1;
+      const auto max = std::numeric_limits<Exponent>::max() / 2;
+
+      // pure power, first variable
+      m.setIdentity(mono);
+      m.setExponent(0, max / firstDeg, mono);
+      ASSERT_TRUE(m.hasAmpleCapacity(mono));
+      m.setExponent(0, max / firstDeg + 1, mono);
+      ASSERT_FALSE(m.hasAmpleCapacity(mono));
+
+      if (varCount == 1)
+        continue;
+
+      // pure power, last variable
+      m.setIdentity(mono);
+      m.setExponent(last, max, mono);
+      ASSERT_TRUE(m.hasAmpleCapacity(mono));
+      m.setExponent(last, max + 1, mono);
+      ASSERT_FALSE(m.hasAmpleCapacity(mono));
+
+      // no exponent is too high but the degree is
+      m.setIdentity(mono);
+      m.setExponent(0, 12, mono);
+      m.setExponent(last, max - 12 * firstDeg, mono);
+      ASSERT_TRUE(m.hasAmpleCapacity(mono));
+      m.setExponent(0, 13, mono);
+      ASSERT_FALSE(m.hasAmpleCapacity(mono));
+    }
+  }
+}
+
+TYPED_TEST(Monoid, CopyEqualConversion) {
+  typedef TypeParam Monoid;
+  typedef typename Monoid::Order Order;
+  typedef typename Monoid::Exponent Exponent;
+  typedef typename Monoid::VarIndex VarIndex;
+  static const bool HasComponent = Monoid::HasComponent;
+  typedef MonoMonoid<Exponent, HasComponent, false, false> MonoidNone;
+  typedef MonoMonoid<Exponent, HasComponent, true, true> MonoidAll;
+  for (VarIndex varCount = 1; varCount < 33; ++varCount) {
+    const Order order
+      (varCount, std::vector<Exponent>(varCount, 1), Order::RevLexBaseOrder);
+    MonoidNone none(order);
+    Monoid some(Monoid::create(none));
+    MonoidAll all(MonoidAll::create(some));
+
+    auto none1 = none.alloc();
+    auto none2 = none.alloc();
+    auto none3 = none.alloc();
+    auto some1 = some.alloc();
+    auto some2 = some.alloc();
+    auto some3 = some.alloc();
+    auto all1 = all.alloc();
+    auto all2 = all.alloc();
+    auto all3 = all.alloc();
+
+    none.setExponent(0, 1, none1);
+    none.setExponent(varCount / 2, 2, none1);
+    none.setExponent(varCount - 1, 3, none1);
+    none.copy(none1, none2);
+    none.setExponent(0, 4, none2);
+
+    some.setExponent(0, 1, some1);
+    some.setExponent(varCount / 2, 2, some1);
+    some.setExponent(varCount - 1, 3, some1);
+    some.copy(some1, some2);
+    some.setExponent(0, 4, some2);
+
+    all.setExponent(0, 1, all1);
+    all.setExponent(varCount / 2, 2, all1);
+    all.setExponent(varCount - 1, 3, all1);
+    all.copy(all1, all2);
+    all.setExponent(0, 4, all2);
+
+    // compare on none
+    ASSERT_TRUE(none.equal(none, none1, none1));
+    ASSERT_TRUE(none.equal(some, some1, none1));
+    ASSERT_TRUE(none.equal(all, all1, none1));
+    ASSERT_FALSE(none.equal(none, none1, none2));
+    ASSERT_FALSE(none.equal(some, some1, none2));
+    ASSERT_FALSE(none.equal(all, all1, none2));
+
+    // compare on some
+    ASSERT_TRUE(some.equal(none, none1, some1));
+    ASSERT_TRUE(some.equal(some, some1, some1));
+    ASSERT_TRUE(some.equal(all, all1, some1));
+    ASSERT_FALSE(some.equal(none, none1, some2));
+    ASSERT_FALSE(some.equal(some, some1, some2));
+    ASSERT_FALSE(some.equal(all, all1, some2));
+
+    // compare on all
+    ASSERT_TRUE(all.equal(none, none1, all1));
+    ASSERT_TRUE(all.equal(some, some1, all1));
+    ASSERT_TRUE(all.equal(all, all1, all1));
+    ASSERT_FALSE(all.equal(none, none1, all2));
+    ASSERT_FALSE(all.equal(some, some1, all2));
+    ASSERT_FALSE(all.equal(all, all1, all2));
+
+    // convert some->none
+    none.copy(some, some1, none3);
+    ASSERT_TRUE(none.equal(none1, none3));
+    ASSERT_FALSE(none.equal(none2, none3));
+    none.copy(some, some2, none3);
+    ASSERT_FALSE(none.equal(none1, none3));
+    ASSERT_TRUE(none.equal(none2, none3));
+
+    /// convert some->all
+    all.copy(some, some1, all3);
+    ASSERT_TRUE(all.equal(all1, all3));
+    ASSERT_FALSE(all.equal(all2, all3));
+    all.copy(some, some2, all3);
+    ASSERT_FALSE(all.equal(all1, all3));
+    ASSERT_TRUE(all.equal(all2, all3));
+
+    // convert none->some
+    some.copy(none, none1, some3);
+    ASSERT_TRUE(some.equal(some1, some3));
+    ASSERT_FALSE(some.equal(some2, some3));
+    some.copy(none, none2, some3);
+    ASSERT_FALSE(some.equal(some1, some3));
+    ASSERT_TRUE(some.equal(some2, some3));
+
+    // convert Y->some
+    some.copy(none, none1, some3);
+    ASSERT_TRUE(some.equal(some1, some3));
+    ASSERT_FALSE(some.equal(some2, some3));
+    some.copy(none, none2, some3);
+    ASSERT_FALSE(some.equal(some1, some3));
+    ASSERT_TRUE(some.equal(some2, some3));
+  }
+}
diff --git a/src/test/PrimeField.cpp b/src/test/PrimeField.cpp
index d52418b..969876f 100755
--- a/src/test/PrimeField.cpp
+++ b/src/test/PrimeField.cpp
@@ -1,9 +1,13 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
-
 #include "mathicgb/PrimeField.hpp"
+
 #include <gtest/gtest.h>
 #include <sstream>
 
+using namespace mgb;
+
 namespace {
   template<class T>
   std::string toString(T&& t) {
diff --git a/src/test/QuadMatrixBuilder.cpp b/src/test/QuadMatrixBuilder.cpp
index 5d9affa..735a489 100755
--- a/src/test/QuadMatrixBuilder.cpp
+++ b/src/test/QuadMatrixBuilder.cpp
@@ -1,244 +1,248 @@
-#include "mathicgb/stdinc.h"
-
-#include "mathicgb/Poly.hpp"
-#include "mathicgb/PolyRing.hpp"
-#include "mathicgb/QuadMatrixBuilder.hpp"
-#include "mathicgb/io-util.hpp"
-#include "mathicgb/Basis.hpp"
-#include "mathicgb/QuadMatrix.hpp"
-#include <gtest/gtest.h>
-
-namespace {
-  std::string monToStr(const PolyRing& ring, ConstMonomial a) {
-    std::ostringstream out;
-    ring.monomialDisplay(out, a, false, true);
-    return out.str();
-  }
-
-  void createColumns(const char* left, const char* right, QuadMatrixBuilder& b)
-  {
-    const PolyRing& ring = b.ring();
-    {
-      Poly p(b.ring());
-      std::istringstream in(left);
-      p.parseDoNotOrder(in);
-      size_t colCount = 0;
-      for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
-        QuadMatrixBuilder::LeftRightColIndex lrCol =
-          b.createColumnLeft(it.getMonomial()).first;
-        ASSERT_TRUE(lrCol.left());
-        ASSERT_FALSE(lrCol.right());
-        auto col = lrCol.leftIndex();
-        ASSERT_EQ(col, lrCol.index());
-        ASSERT_EQ(colCount, col);
-        ++colCount;
-      }
-    }
-    {
-      Poly p(b.ring());
-      std::istringstream in(right);
-      p.parseDoNotOrder(in);
-      size_t colCount = 0;
-      for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
-        QuadMatrixBuilder::LeftRightColIndex lrCol =
-          b.createColumnRight(it.getMonomial()).first;
-        ASSERT_TRUE(lrCol.right());
-        ASSERT_FALSE(lrCol.left());
-        auto col = lrCol.rightIndex();
-        ASSERT_EQ(col, lrCol.index());
-        ASSERT_EQ(colCount, col);
-        ++colCount;
-      }
-    }
-  }
-}
-
-TEST(QuadMatrixBuilder, Empty) {
-  // test a builder with no rows and no columns
-  PolyRing ring(2, PolyRing::Monoid(0));
-  QuadMatrixBuilder::Map map(ring);
-  QuadMatrixBuilder::MonomialsType monoLeft;
-  QuadMatrixBuilder::MonomialsType monoRight;
-  QuadMatrixBuilder b(ring, map, monoLeft, monoRight);
-  const char* matrixStr = 
-    "Left columns:\n"
-    "Right columns:\n"
-    "matrix with no rows | matrix with no rows\n"
-    "                    |                    \n"
-    "matrix with no rows | matrix with no rows\n";
-  auto matrix = b.buildMatrixAndClear();
-  matrix.leftColumnMonomials = monoLeft;
-  matrix.rightColumnMonomials = monoRight;
-  ASSERT_EQ(matrixStr, matrix.toString());
-}
-
-TEST(QuadMatrixBuilder, Construction) {
-  std::unique_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
-  QuadMatrixBuilder::Map map(*ring);
-  QuadMatrixBuilder::MonomialsType monoLeft;
-  QuadMatrixBuilder::MonomialsType monoRight;
-  QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
-  createColumns("a<1>+<0>", "bc<0>+b<0>+c<0>", b);
-
-  // top row: nothing, nothing
-  b.rowDoneTopLeftAndRight();
-
-  // top row: 0#1 1#2, 2#3
-  b.appendEntryTopLeft(0, 1);
-  b.appendEntryTopLeft(1, 2);
-  b.appendEntryTopRight(2, 3);
-  b.rowDoneTopLeftAndRight();
-
-  // bottom row: 1#4, nothing
-  b.appendEntryBottomLeft(1,4);
-  b.rowDoneBottomLeftAndRight();
-
-  // bottom row: nothing, 0#5
-  b.appendEntryBottomRight(0,5);
-  b.rowDoneBottomLeftAndRight();
-
-  // bottom row: nothing, nothing
-  b.rowDoneBottomLeftAndRight();
-
-  const char* matrixStr =
-    "Left columns: a 1\n"
-    "Right columns: bc b c\n"
-    "0:         | 0:    \n"
-    "1: 0#1 1#2 | 1: 2#3\n"
-    "           |       \n"
-    "0: 1#4     | 0:    \n"
-    "1:         | 1: 0#5\n"
-    "2:         | 2:    \n";
-  auto matrix = b.buildMatrixAndClear();
-  matrix.leftColumnMonomials = monoLeft;
-  matrix.rightColumnMonomials = monoRight;
-  ASSERT_EQ(matrixStr, matrix.toString());
-}
-
-TEST(QuadMatrixBuilder, ColumnQuery) {
-  std::unique_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
-  QuadMatrixBuilder::Map map(*ring);
-  QuadMatrixBuilder::MonomialsType monoLeft;
-  QuadMatrixBuilder::MonomialsType monoRight;
-  QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
-  createColumns("a<1>+<0>", "b<0>+c<0>+bc<0>", b);
-
-  Poly p(b.ring());
-  // coefficient 1X=left, 2X=right, 30=not there, % 10 = column index
-  std::istringstream in
-    ("10a<1>+11<0>+20b<0>+21c<0>+22bc<0>+30ab<0>+30e<0>+10a<1>");
-  p.parseDoNotOrder(in);
-  for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
-    const QuadMatrixBuilder::LeftRightColIndex* col =
-      MonomialMap<QuadMatrixBuilder::LeftRightColIndex>::Reader(map).find(it.getMonomial()).first;
-    if (it.getCoefficient() / 10 == 3)
-      ASSERT_EQ(col, static_cast<void*>(0));
-    else {
-      ASSERT_TRUE(col != static_cast<void*>(0));
-      ASSERT_EQ(it.getCoefficient() % 10, col->index());
-      if (it.getCoefficient() / 10 == 2)
-        ASSERT_TRUE(col->right());
-      else
-        ASSERT_TRUE(col->left());
-    }
-  }
-}
-
-TEST(QuadMatrixBuilder, SortColumns) {
-  // construct builder and reverse lex order
-  std::unique_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
-  Basis basis(*ring);
-  
-  // one row top, no rows bottom, no columns
-  {
-    QuadMatrixBuilder::Map map(*ring);
-    QuadMatrixBuilder::MonomialsType monoLeft;
-    QuadMatrixBuilder::MonomialsType monoRight;
-    QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
-    b.rowDoneTopLeftAndRight();
-    auto matrix = b.buildMatrixAndClear();
-    matrix.sortColumnsLeftRightParallel();
-    const char* matrixStr = 
-      "Left columns:\n"
-      "Right columns:\n"
-      "0:                  | 0:                 \n"
-      "                    |                    \n"
-      "matrix with no rows | matrix with no rows\n";
-    ASSERT_EQ(matrixStr, matrix.toString());
-  }
-
-  {
-    QuadMatrixBuilder::Map map(*ring);
-    QuadMatrixBuilder::MonomialsType monoLeft;
-    QuadMatrixBuilder::MonomialsType monoRight;
-    QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
-    createColumns("<0>+a<0>", "b<0>+bcd<0>+bc<0>", b);
-    b.appendEntryTopLeft(0,1);
-    b.appendEntryTopLeft(1,2);
-    b.appendEntryTopRight(0,3);
-    b.appendEntryTopRight(1,4);
-    b.appendEntryTopRight(2,5);
-    b.rowDoneTopLeftAndRight();
-
-    b.appendEntryBottomLeft(0,6);
-    b.appendEntryBottomLeft(1,7);
-    b.appendEntryBottomRight(0,8);
-    b.appendEntryBottomRight(1,9);
-    b.appendEntryBottomRight(2,10);
-    b.rowDoneBottomLeftAndRight();
-    auto matrix = b.buildMatrixAndClear();
-    matrix.leftColumnMonomials = monoLeft;
-    matrix.rightColumnMonomials = monoRight;
-
-    const char* matrixStr1 =
-      "Left columns: 1 a\n"
-      "Right columns: b bcd bc\n"
-      "0: 0#1 1#2 | 0: 0#3 1#4 2#5 \n"
-      "           |                \n"
-      "0: 0#6 1#7 | 0: 0#8 1#9 2#10\n";
-    ASSERT_EQ(matrixStr1, matrix.toString());
-
-    const char* matrixStr2 =
-      "Left columns: a 1\n"
-      "Right columns: bcd bc b\n"
-      "0: 1#1 0#2 | 0: 2#3 0#4 1#5 \n"
-      "           |                \n"
-      "0: 1#6 0#7 | 0: 2#8 0#9 1#10\n";
-    matrix.sortColumnsLeftRightParallel();
-    ASSERT_EQ(matrixStr2, matrix.toString());
-
-    matrix.sortColumnsLeftRightParallel();
-    ASSERT_EQ(matrixStr2, matrix.toString());
-  }
-}
-
-TEST(QuadMatrixBuilder, BuildAndClear) {
-  std::unique_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
-  QuadMatrixBuilder::Map map(*ring);
-  QuadMatrixBuilder::MonomialsType monoLeft;
-  QuadMatrixBuilder::MonomialsType monoRight;
-  QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
-  createColumns("a<1>+<0>", "b<0>+c<0>+bc<0>", b);
-
-  b.appendEntryTopLeft(1, 1);
-  b.appendEntryTopRight(2, 2);
-  b.rowDoneTopLeftAndRight();
-
-  b.appendEntryBottomLeft(1, 3);
-  b.appendEntryBottomRight(2, 4);
-  b.rowDoneBottomLeftAndRight();
-
-  QuadMatrix qm(b.buildMatrixAndClear());
-  qm.leftColumnMonomials = monoLeft;
-  qm.rightColumnMonomials = monoRight;
-
-  // test that the quad matrix is right
-  ASSERT_EQ("0: 1#1\n", qm.topLeft.toString());
-  ASSERT_EQ("0: 2#2\n", qm.topRight.toString());
-  ASSERT_EQ("0: 1#3\n", qm.bottomLeft.toString());
-  ASSERT_EQ("0: 2#4\n", qm.bottomRight.toString());
-  ASSERT_EQ(2, qm.leftColumnMonomials.size());
-  ASSERT_EQ(3, qm.rightColumnMonomials.size());
-  ASSERT_EQ("a", monToStr(*ring, qm.leftColumnMonomials[0]));
-  ASSERT_EQ("b", monToStr(*ring, qm.rightColumnMonomials[0]));
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+#include "mathicgb/QuadMatrixBuilder.hpp"
+
+#include "mathicgb/Poly.hpp"
+#include "mathicgb/PolyRing.hpp"
+#include "mathicgb/io-util.hpp"
+#include "mathicgb/Basis.hpp"
+#include "mathicgb/QuadMatrix.hpp"
+#include <gtest/gtest.h>
+
+using namespace mgb;
+
+namespace {
+  ::std::string monToStr(const PolyRing& ring, ConstMonomial a) {
+    ::std::ostringstream out;
+    ring.monomialDisplay(out, a, false, true);
+    return out.str();
+  }
+
+  void createColumns(const char* left, const char* right, QuadMatrixBuilder& b)
+  {
+    const PolyRing& ring = b.ring();
+    {
+      Poly p(b.ring());
+      ::std::istringstream in(left);
+      p.parseDoNotOrder(in);
+      size_t colCount = 0;
+      for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
+        QuadMatrixBuilder::LeftRightColIndex lrCol =
+          b.createColumnLeft(it.getMonomial()).first;
+        ASSERT_TRUE(lrCol.left());
+        ASSERT_FALSE(lrCol.right());
+        auto col = lrCol.leftIndex();
+        ASSERT_EQ(col, lrCol.index());
+        ASSERT_EQ(colCount, col);
+        ++colCount;
+      }
+    }
+    {
+      Poly p(b.ring());
+      ::std::istringstream in(right);
+      p.parseDoNotOrder(in);
+      size_t colCount = 0;
+      for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
+        QuadMatrixBuilder::LeftRightColIndex lrCol =
+          b.createColumnRight(it.getMonomial()).first;
+        ASSERT_TRUE(lrCol.right());
+        ASSERT_FALSE(lrCol.left());
+        auto col = lrCol.rightIndex();
+        ASSERT_EQ(col, lrCol.index());
+        ASSERT_EQ(colCount, col);
+        ++colCount;
+      }
+    }
+  }
+}
+
+TEST(QuadMatrixBuilder, Empty) {
+  // test a builder with no rows and no columns
+  PolyRing ring(2, PolyRing::Monoid(0));
+  QuadMatrixBuilder::Map map(ring);
+  QuadMatrixBuilder::MonomialsType monoLeft;
+  QuadMatrixBuilder::MonomialsType monoRight;
+  QuadMatrixBuilder b(ring, map, monoLeft, monoRight);
+  const char* matrixStr = 
+    "Left columns:\n"
+    "Right columns:\n"
+    "matrix with no rows | matrix with no rows\n"
+    "                    |                    \n"
+    "matrix with no rows | matrix with no rows\n";
+  auto matrix = b.buildMatrixAndClear();
+  matrix.leftColumnMonomials = monoLeft;
+  matrix.rightColumnMonomials = monoRight;
+  ASSERT_EQ(matrixStr, matrix.toString());
+}
+
+TEST(QuadMatrixBuilder, Construction) {
+  ::std::unique_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
+  QuadMatrixBuilder::Map map(*ring);
+  QuadMatrixBuilder::MonomialsType monoLeft;
+  QuadMatrixBuilder::MonomialsType monoRight;
+  QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
+  createColumns("a<1>+<0>", "bc<0>+b<0>+c<0>", b);
+
+  // top row: nothing, nothing
+  b.rowDoneTopLeftAndRight();
+
+  // top row: 0#1 1#2, 2#3
+  b.appendEntryTopLeft(0, 1);
+  b.appendEntryTopLeft(1, 2);
+  b.appendEntryTopRight(2, 3);
+  b.rowDoneTopLeftAndRight();
+
+  // bottom row: 1#4, nothing
+  b.appendEntryBottomLeft(1,4);
+  b.rowDoneBottomLeftAndRight();
+
+  // bottom row: nothing, 0#5
+  b.appendEntryBottomRight(0,5);
+  b.rowDoneBottomLeftAndRight();
+
+  // bottom row: nothing, nothing
+  b.rowDoneBottomLeftAndRight();
+
+  const char* matrixStr =
+    "Left columns: a 1\n"
+    "Right columns: bc b c\n"
+    "0:         | 0:    \n"
+    "1: 0#1 1#2 | 1: 2#3\n"
+    "           |       \n"
+    "0: 1#4     | 0:    \n"
+    "1:         | 1: 0#5\n"
+    "2:         | 2:    \n";
+  auto matrix = b.buildMatrixAndClear();
+  matrix.leftColumnMonomials = monoLeft;
+  matrix.rightColumnMonomials = monoRight;
+  ASSERT_EQ(matrixStr, matrix.toString());
+}
+
+TEST(QuadMatrixBuilder, ColumnQuery) {
+  ::std::unique_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
+  QuadMatrixBuilder::Map map(*ring);
+  QuadMatrixBuilder::MonomialsType monoLeft;
+  QuadMatrixBuilder::MonomialsType monoRight;
+  QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
+  createColumns("a<1>+<0>", "b<0>+c<0>+bc<0>", b);
+
+  Poly p(b.ring());
+  // coefficient 1X=left, 2X=right, 30=not there, % 10 = column index
+  ::std::istringstream in
+    ("10a<1>+11<0>+20b<0>+21c<0>+22bc<0>+30ab<0>+30e<0>+10a<1>");
+  p.parseDoNotOrder(in);
+  for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
+    const QuadMatrixBuilder::LeftRightColIndex* col =
+      MonomialMap<QuadMatrixBuilder::LeftRightColIndex>::Reader(map).find(it.getMonomial()).first;
+    if (it.getCoefficient() / 10 == 3)
+      ASSERT_EQ(col, static_cast<void*>(0));
+    else {
+      ASSERT_TRUE(col != static_cast<void*>(0));
+      ASSERT_EQ(it.getCoefficient() % 10, col->index());
+      if (it.getCoefficient() / 10 == 2)
+        ASSERT_TRUE(col->right());
+      else
+        ASSERT_TRUE(col->left());
+    }
+  }
+}
+
+TEST(QuadMatrixBuilder, SortColumns) {
+  // construct builder and reverse lex order
+  ::std::unique_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
+  Basis basis(*ring);
+  
+  // one row top, no rows bottom, no columns
+  {
+    QuadMatrixBuilder::Map map(*ring);
+    QuadMatrixBuilder::MonomialsType monoLeft;
+    QuadMatrixBuilder::MonomialsType monoRight;
+    QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
+    b.rowDoneTopLeftAndRight();
+    auto matrix = b.buildMatrixAndClear();
+    matrix.sortColumnsLeftRightParallel();
+    const char* matrixStr = 
+      "Left columns:\n"
+      "Right columns:\n"
+      "0:                  | 0:                 \n"
+      "                    |                    \n"
+      "matrix with no rows | matrix with no rows\n";
+    ASSERT_EQ(matrixStr, matrix.toString());
+  }
+
+  {
+    QuadMatrixBuilder::Map map(*ring);
+    QuadMatrixBuilder::MonomialsType monoLeft;
+    QuadMatrixBuilder::MonomialsType monoRight;
+    QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
+    createColumns("<0>+a<0>", "b<0>+bcd<0>+bc<0>", b);
+    b.appendEntryTopLeft(0,1);
+    b.appendEntryTopLeft(1,2);
+    b.appendEntryTopRight(0,3);
+    b.appendEntryTopRight(1,4);
+    b.appendEntryTopRight(2,5);
+    b.rowDoneTopLeftAndRight();
+
+    b.appendEntryBottomLeft(0,6);
+    b.appendEntryBottomLeft(1,7);
+    b.appendEntryBottomRight(0,8);
+    b.appendEntryBottomRight(1,9);
+    b.appendEntryBottomRight(2,10);
+    b.rowDoneBottomLeftAndRight();
+    auto matrix = b.buildMatrixAndClear();
+    matrix.leftColumnMonomials = monoLeft;
+    matrix.rightColumnMonomials = monoRight;
+
+    const char* matrixStr1 =
+      "Left columns: 1 a\n"
+      "Right columns: b bcd bc\n"
+      "0: 0#1 1#2 | 0: 0#3 1#4 2#5 \n"
+      "           |                \n"
+      "0: 0#6 1#7 | 0: 0#8 1#9 2#10\n";
+    ASSERT_EQ(matrixStr1, matrix.toString());
+
+    const char* matrixStr2 =
+      "Left columns: a 1\n"
+      "Right columns: bcd bc b\n"
+      "0: 1#1 0#2 | 0: 2#3 0#4 1#5 \n"
+      "           |                \n"
+      "0: 1#6 0#7 | 0: 2#8 0#9 1#10\n";
+    matrix.sortColumnsLeftRightParallel();
+    ASSERT_EQ(matrixStr2, matrix.toString());
+
+    matrix.sortColumnsLeftRightParallel();
+    ASSERT_EQ(matrixStr2, matrix.toString());
+  }
+}
+
+TEST(QuadMatrixBuilder, BuildAndClear) {
+  ::std::unique_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
+  QuadMatrixBuilder::Map map(*ring);
+  QuadMatrixBuilder::MonomialsType monoLeft;
+  QuadMatrixBuilder::MonomialsType monoRight;
+  QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
+  createColumns("a<1>+<0>", "b<0>+c<0>+bc<0>", b);
+
+  b.appendEntryTopLeft(1, 1);
+  b.appendEntryTopRight(2, 2);
+  b.rowDoneTopLeftAndRight();
+
+  b.appendEntryBottomLeft(1, 3);
+  b.appendEntryBottomRight(2, 4);
+  b.rowDoneBottomLeftAndRight();
+
+  QuadMatrix qm(b.buildMatrixAndClear());
+  qm.leftColumnMonomials = monoLeft;
+  qm.rightColumnMonomials = monoRight;
+
+  // test that the quad matrix is right
+  ASSERT_EQ("0: 1#1\n", qm.topLeft.toString());
+  ASSERT_EQ("0: 2#2\n", qm.topRight.toString());
+  ASSERT_EQ("0: 1#3\n", qm.bottomLeft.toString());
+  ASSERT_EQ("0: 2#4\n", qm.bottomRight.toString());
+  ASSERT_EQ(2, qm.leftColumnMonomials.size());
+  ASSERT_EQ(3, qm.rightColumnMonomials.size());
+  ASSERT_EQ("a", monToStr(*ring, qm.leftColumnMonomials[0]));
+  ASSERT_EQ("b", monToStr(*ring, qm.rightColumnMonomials[0]));
+}
diff --git a/src/test/Scanner.cpp b/src/test/Scanner.cpp
index d1dcf98..d1aefd2 100755
--- a/src/test/Scanner.cpp
+++ b/src/test/Scanner.cpp
@@ -1,120 +1,124 @@
-#include "mathicgb/stdinc.h"
-#include "mathicgb/Scanner.hpp"
-
-#include <gtest/gtest.h>
-
-namespace {
-  const char* const alpha = "abcdefghijkl";
-  const char* const alphaSpaced = "a bc def ghij kl";
-  const char* const alphas[] = {"a", "bc", "def", "ghij", "kl"};
-}
-
-TEST(Scanner, NoOp) {
-  std::istringstream in;
-  Scanner sc(in);
-}
-
-TEST(Scanner, PeekAndGet) {
-  std::stringstream s(alphaSpaced);
-  Scanner in(s);
-  for (size_t i = 0; alpha[i] != '\0'; ++i) {
-    ASSERT_EQ(alphaSpaced[i], in.peek());
-    ASSERT_EQ(alphaSpaced[i], in.get());
-  }
-}
-
-TEST(Scanner, Match) {
-  std::stringstream s(alphaSpaced);
-  Scanner in(s);
-  for (size_t i = 0; alpha[i] != '\0'; ++i) {
-    ASSERT_FALSE(in.match('!'));
-    ASSERT_FALSE(in.matchEOF());
-    ASSERT_TRUE(in.match(alpha[i]));
-  }
-  ASSERT_TRUE(in.matchEOF());
-}
-
-TEST(Scanner, ExpectChar) {
-  std::stringstream s(alphaSpaced);
-  Scanner in(s);
-  for (size_t i = 0; alpha[i] != '\0'; ++i)
-    in.expect(alpha[i]);
-  in.expectEOF();
-}
-
-TEST(Scanner, ExpectTwoChars) {
-  Scanner in(alphaSpaced);
-  for (size_t i = 0; alpha[i] != '\0'; ++i) {
-    if (i % 2 == 0)
-      in.expect('!', alpha[i]);
-    else
-      in.expect(alpha[i], '!');
-  }
-  in.expectEOF();
-}
-
-TEST(Scanner, ExpectString) {
-  Scanner in{std::string(alphaSpaced)};
-  const auto size = sizeof(alphas) / sizeof(*alphas);
-  for (size_t i = 0; i < size; ++i) {
-    if (i % 2 == 0)
-      in.expect(alphas[i]);
-    else
-      in.expect(std::string(alphas[i]));
-  }
-}
-
-TEST(Scanner, MatchString) {
-  Scanner in{std::string(alphaSpaced)};
-  const auto size = sizeof(alphas) / sizeof(*alphas);
-  for (size_t i = 0; i < size; ++i) {
-    ASSERT_FALSE(in.match("ef"));
-    ASSERT_FALSE(in.match("deq"));
-    ASSERT_TRUE(in.match(alphas[i]));
-  }
-}
-
-TEST(Scanner, readModular) {
-  PrimeField<unsigned char> f(11);
-  std::stringstream s("0 1 1 +0 -0 +1 -1 15 255 -255");
-  Scanner in(s);
-  ASSERT_EQ(f.zero(), in.readModular(f));
-  ASSERT_EQ(f.one(), in.readModular(f));
-  ASSERT_EQ(f.minusOne(), in.readModular(f, true));
-  ASSERT_EQ(f.zero(), in.readModular(f));
-  ASSERT_EQ(f.zero(), in.readModular(f));
-  ASSERT_EQ(f.one(), in.readModular(f));
-  ASSERT_EQ(f.minusOne(), in.readModular(f));
-  ASSERT_EQ(f.toElement(4), in.readModular(f));
-  ASSERT_EQ(f.toElement(2), in.readModular(f));
-  ASSERT_EQ(f.toElement(9), in.readModular(f));
-}
-
-TEST(Scanner, readInteger) {
-  std::stringstream s("0 1 +0 -0 +1 -1 127 -128 128");
-  Scanner in(s);
-  ASSERT_EQ(0, in.readInteger<signed char>());
-  ASSERT_EQ(1, in.readInteger<char>());
-  ASSERT_EQ(0, in.readInteger<unsigned char>());
-  ASSERT_EQ(0, in.readInteger<char>());
-  ASSERT_EQ(1, in.readInteger<char>());
-  ASSERT_EQ(-1, in.readInteger<char>());
-  ASSERT_EQ(127, in.readInteger<char>());
-  ASSERT_EQ(-128, in.readInteger<char>());
-  ASSERT_EQ(-128, in.readInteger<char>(true));
-}
-
-TEST(Scanner, WhiteAndLineCount) {
-  std::stringstream s(" \t\n\rx\n\n\ny");
-  Scanner in(s);
-  ASSERT_EQ(1, in.lineCount());
-  ASSERT_TRUE(in.peek() == ' ');
-  ASSERT_TRUE(in.peekWhite());
-  in.eatWhite();
-  ASSERT_TRUE(in.peek() == 'x');
-  ASSERT_TRUE(in.match('x'));
-  ASSERT_EQ(2, in.lineCount());
-  ASSERT_TRUE(in.match('y'));
-  in.expectEOF();
-  ASSERT_EQ(5, in.lineCount());
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+#include "mathicgb/Scanner.hpp"
+
+#include <gtest/gtest.h>
+
+using namespace mgb;
+
+namespace {
+  const char* const alpha = "abcdefghijkl";
+  const char* const alphaSpaced = "a bc def ghij kl";
+  const char* const alphas[] = {"a", "bc", "def", "ghij", "kl"};
+}
+
+TEST(Scanner, NoOp) {
+  std::istringstream in;
+  Scanner sc(in);
+}
+
+TEST(Scanner, PeekAndGet) {
+  std::stringstream s(alphaSpaced);
+  Scanner in(s);
+  for (size_t i = 0; alpha[i] != '\0'; ++i) {
+    ASSERT_EQ(alphaSpaced[i], in.peek());
+    ASSERT_EQ(alphaSpaced[i], in.get());
+  }
+}
+
+TEST(Scanner, Match) {
+  std::stringstream s(alphaSpaced);
+  Scanner in(s);
+  for (size_t i = 0; alpha[i] != '\0'; ++i) {
+    ASSERT_FALSE(in.match('!'));
+    ASSERT_FALSE(in.matchEOF());
+    ASSERT_TRUE(in.match(alpha[i]));
+  }
+  ASSERT_TRUE(in.matchEOF());
+}
+
+TEST(Scanner, ExpectChar) {
+  std::stringstream s(alphaSpaced);
+  Scanner in(s);
+  for (size_t i = 0; alpha[i] != '\0'; ++i)
+    in.expect(alpha[i]);
+  in.expectEOF();
+}
+
+TEST(Scanner, ExpectTwoChars) {
+  Scanner in(alphaSpaced);
+  for (size_t i = 0; alpha[i] != '\0'; ++i) {
+    if (i % 2 == 0)
+      in.expect('!', alpha[i]);
+    else
+      in.expect(alpha[i], '!');
+  }
+  in.expectEOF();
+}
+
+TEST(Scanner, ExpectString) {
+  Scanner in{std::string(alphaSpaced)};
+  const auto size = sizeof(alphas) / sizeof(*alphas);
+  for (size_t i = 0; i < size; ++i) {
+    if (i % 2 == 0)
+      in.expect(alphas[i]);
+    else
+      in.expect(std::string(alphas[i]));
+  }
+}
+
+TEST(Scanner, MatchString) {
+  Scanner in{std::string(alphaSpaced)};
+  const auto size = sizeof(alphas) / sizeof(*alphas);
+  for (size_t i = 0; i < size; ++i) {
+    ASSERT_FALSE(in.match("ef"));
+    ASSERT_FALSE(in.match("deq"));
+    ASSERT_TRUE(in.match(alphas[i]));
+  }
+}
+
+TEST(Scanner, readModular) {
+  PrimeField<unsigned char> f(11);
+  std::stringstream s("0 1 1 +0 -0 +1 -1 15 255 -255");
+  Scanner in(s);
+  ASSERT_EQ(f.zero(), in.readModular(f));
+  ASSERT_EQ(f.one(), in.readModular(f));
+  ASSERT_EQ(f.minusOne(), in.readModular(f, true));
+  ASSERT_EQ(f.zero(), in.readModular(f));
+  ASSERT_EQ(f.zero(), in.readModular(f));
+  ASSERT_EQ(f.one(), in.readModular(f));
+  ASSERT_EQ(f.minusOne(), in.readModular(f));
+  ASSERT_EQ(f.toElement(4), in.readModular(f));
+  ASSERT_EQ(f.toElement(2), in.readModular(f));
+  ASSERT_EQ(f.toElement(9), in.readModular(f));
+}
+
+TEST(Scanner, readInteger) {
+  std::stringstream s("0 1 +0 -0 +1 -1 127 -128 128");
+  Scanner in(s);
+  ASSERT_EQ(0, in.readInteger<signed char>());
+  ASSERT_EQ(1, in.readInteger<char>());
+  ASSERT_EQ(0, in.readInteger<unsigned char>());
+  ASSERT_EQ(0, in.readInteger<char>());
+  ASSERT_EQ(1, in.readInteger<char>());
+  ASSERT_EQ(-1, in.readInteger<char>());
+  ASSERT_EQ(127, in.readInteger<char>());
+  ASSERT_EQ(-128, in.readInteger<char>());
+  ASSERT_EQ(-128, in.readInteger<char>(true));
+}
+
+TEST(Scanner, WhiteAndLineCount) {
+  std::stringstream s(" \t\n\rx\n\n\ny");
+  Scanner in(s);
+  ASSERT_EQ(1, in.lineCount());
+  ASSERT_TRUE(in.peek() == ' ');
+  ASSERT_TRUE(in.peekWhite());
+  in.eatWhite();
+  ASSERT_TRUE(in.peek() == 'x');
+  ASSERT_TRUE(in.match('x'));
+  ASSERT_EQ(2, in.lineCount());
+  ASSERT_TRUE(in.match('y'));
+  in.expectEOF();
+  ASSERT_EQ(5, in.lineCount());
+}
diff --git a/src/test/SparseMatrix.cpp b/src/test/SparseMatrix.cpp
index d140553..d07eb54 100755
--- a/src/test/SparseMatrix.cpp
+++ b/src/test/SparseMatrix.cpp
@@ -1,85 +1,90 @@
-#include "mathicgb/stdinc.h"
-
-#include "mathicgb/SparseMatrix.hpp"
-#include "mathicgb/Poly.hpp"
-#include "mathicgb/PolyRing.hpp"
-#include "mathicgb/io-util.hpp"
-#include <gtest/gtest.h>
-#include <memory>
-
-namespace {
-  std::unique_ptr<Poly> parsePoly(const PolyRing& ring, std::string str) {
-    auto p = make_unique<Poly>(ring);
-    std::istringstream in(str);
-    p->parse(in);
-    return p;
-  }
-}
-
-TEST(SparseMatrix, NoRows) {
-  SparseMatrix mat; // test a matrix with no rows
-  ASSERT_EQ(0, mat.entryCount());
-  ASSERT_EQ(0, mat.rowCount());
-  ASSERT_EQ(0, mat.computeColCount());
-  ASSERT_EQ("matrix with no rows\n", mat.toString()); 
-}
-
-TEST(SparseMatrix, Simple) {
-  SparseMatrix mat;
-
-  mat.appendEntry(5, 101);
-  mat.rowDone();
-  ASSERT_EQ(1, mat.entryCount());
-  ASSERT_EQ(1, mat.rowCount());
-  ASSERT_EQ(6, mat.computeColCount());
-  ASSERT_EQ(5, mat.leadCol(0));
-  ASSERT_EQ(1, mat.entryCountInRow(0));
-  ASSERT_EQ("0: 5#101\n", mat.toString()); 
-  ASSERT_FALSE(mat.emptyRow(0));
-
-  mat.rowDone(); // add a row with no entries
-  ASSERT_EQ(1, mat.entryCount());
-  ASSERT_EQ(2, mat.rowCount());
-  ASSERT_EQ(6, mat.computeColCount());
-  ASSERT_EQ(5, mat.leadCol(0));
-  ASSERT_EQ(0, mat.entryCountInRow(1));
-  ASSERT_EQ("0: 5#101\n1:\n", mat.toString()); 
-  ASSERT_TRUE(mat.emptyRow(1));
-
-  mat.appendEntry(5, 102);
-  mat.appendEntry(2001, 0); // scalar zero
-  mat.rowDone(); // add a row with two entries
-  ASSERT_EQ(3, mat.entryCount());
-  ASSERT_EQ(3, mat.rowCount());
-  ASSERT_EQ(2002, mat.computeColCount());
-  ASSERT_EQ(5, mat.leadCol(2));
-  ASSERT_EQ(2, mat.entryCountInRow(2));
-  ASSERT_EQ("0: 5#101\n1:\n2: 5#102 2001#0\n", mat.toString()); 
-  ASSERT_FALSE(mat.emptyRow(2));
-}
-
-TEST(SparseMatrix, toRow) {
-  auto ring = ringFromString("32003 6 1\n1 1 1 1 1 1");
-  auto polyForMonomials = parsePoly(*ring, "a5+a4+a3+a2+a1+a0");
-  std::vector<monomial> monomials;
-  for (auto it = polyForMonomials->begin(); it != polyForMonomials->end(); ++it)
-    monomials.push_back(it.getMonomial());
-
-  SparseMatrix mat(5);
-  mat.clear();
-  mat.rowDone();
-  mat.appendEntry(0,10);
-  mat.rowDone();
-  mat.appendEntry(2,20);
-  mat.appendEntry(3,0);
-  mat.appendEntry(4,40);
-  mat.rowDone();
-
-  Poly p(*ring);
-  mat.rowToPolynomial(0, monomials, p);
-  ASSERT_EQ(*parsePoly(*ring, "0"), p);
-  mat.rowToPolynomial(1, monomials, p);
-  ASSERT_EQ(*parsePoly(*ring, "10a5"), p);
-  mat.rowToPolynomial(2, monomials, p);
-  ASSERT_EQ(*parsePoly(*ring, "20a3+40a1"), p);
-}
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+#include "mathicgb/SparseMatrix.hpp"
+
+#include "mathicgb/Poly.hpp"
+#include "mathicgb/PolyRing.hpp"
+#include "mathicgb/io-util.hpp"
+#include <gtest/gtest.h>
+#include <memory>
+#include <string>
+
+using namespace mgb;
+
+namespace {
+  ::std::unique_ptr<Poly> parsePoly(const PolyRing& ring, ::std::string str) {
+    auto p = make_unique<Poly>(ring);
+    ::std::istringstream in(str);
+    p->parse(in);
+    return p;
+  }
+}
+
+TEST(SparseMatrix, NoRows) {
+  SparseMatrix mat; // test a matrix with no rows
+  ASSERT_EQ(0, mat.entryCount());
+  ASSERT_EQ(0, mat.rowCount());
+  ASSERT_EQ(0, mat.computeColCount());
+  ASSERT_EQ("matrix with no rows\n", mat.toString()); 
+}
+
+TEST(SparseMatrix, Simple) {
+  SparseMatrix mat;
+
+  mat.appendEntry(5, 101);
+  mat.rowDone();
+  ASSERT_EQ(1, mat.entryCount());
+  ASSERT_EQ(1, mat.rowCount());
+  ASSERT_EQ(6, mat.computeColCount());
+  ASSERT_EQ(5, mat.leadCol(0));
+  ASSERT_EQ(1, mat.entryCountInRow(0));
+  ASSERT_EQ("0: 5#101\n", mat.toString()); 
+  ASSERT_FALSE(mat.emptyRow(0));
+
+  mat.rowDone(); // add a row with no entries
+  ASSERT_EQ(1, mat.entryCount());
+  ASSERT_EQ(2, mat.rowCount());
+  ASSERT_EQ(6, mat.computeColCount());
+  ASSERT_EQ(5, mat.leadCol(0));
+  ASSERT_EQ(0, mat.entryCountInRow(1));
+  ASSERT_EQ("0: 5#101\n1:\n", mat.toString()); 
+  ASSERT_TRUE(mat.emptyRow(1));
+
+  mat.appendEntry(5, 102);
+  mat.appendEntry(2001, 0); // scalar zero
+  mat.rowDone(); // add a row with two entries
+  ASSERT_EQ(3, mat.entryCount());
+  ASSERT_EQ(3, mat.rowCount());
+  ASSERT_EQ(2002, mat.computeColCount());
+  ASSERT_EQ(5, mat.leadCol(2));
+  ASSERT_EQ(2, mat.entryCountInRow(2));
+  ASSERT_EQ("0: 5#101\n1:\n2: 5#102 2001#0\n", mat.toString()); 
+  ASSERT_FALSE(mat.emptyRow(2));
+}
+
+TEST(SparseMatrix, toRow) {
+  auto ring = ringFromString("32003 6 1\n1 1 1 1 1 1");
+  auto polyForMonomials = parsePoly(*ring, "a5+a4+a3+a2+a1+a0");
+  ::std::vector<monomial> monomials;
+  for (auto it = polyForMonomials->begin(); it != polyForMonomials->end(); ++it)
+    monomials.push_back(it.getMonomial());
+
+  SparseMatrix mat(5);
+  mat.clear();
+  mat.rowDone();
+  mat.appendEntry(0,10);
+  mat.rowDone();
+  mat.appendEntry(2,20);
+  mat.appendEntry(3,0);
+  mat.appendEntry(4,40);
+  mat.rowDone();
+
+  Poly p(*ring);
+  mat.rowToPolynomial(0, monomials, p);
+  ASSERT_EQ(*parsePoly(*ring, "0"), p);
+  mat.rowToPolynomial(1, monomials, p);
+  ASSERT_EQ(*parsePoly(*ring, "10a5"), p);
+  mat.rowToPolynomial(2, monomials, p);
+  ASSERT_EQ(*parsePoly(*ring, "20a3+40a1"), p);
+}
diff --git a/src/test/gb-test.cpp b/src/test/gb-test.cpp
index a43eeeb..8285b4b 100755
--- a/src/test/gb-test.cpp
+++ b/src/test/gb-test.cpp
@@ -1,5 +1,5 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
 
 #include "mathicgb/Poly.hpp"
@@ -15,7 +15,6 @@
 #include "mathicgb/MathicIO.hpp"
 #include "mathicgb/Scanner.hpp"
 #include "test/ideals.hpp"
-
 #include <cstdio>
 #include <string>
 #include <iostream>
@@ -23,6 +22,8 @@
 #include <memory>
 #include <gtest/gtest.h>
 
+using namespace mgb;
+
 TEST(IO, ideal) {
   const char* idealA_fromStr_format = 
 "32003 6 \
@@ -407,8 +408,3 @@ TEST(GB, gerdt93_0_7) {
   testGB(gerdt93IdealComponentFirst(false), gerdt93_gb_strat0_free7,
          gerdt93_syzygies_strat0_free7, gerdt93_initial_strat0_free7, 9);
 }
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/test/gtestInclude.cpp b/src/test/gtestInclude.cpp
index a14f48f..3d48078 100755
--- a/src/test/gtestInclude.cpp
+++ b/src/test/gtestInclude.cpp
@@ -1,10 +1,17 @@
-// Includes a file from gtest that pulls in all of the implementation
-// of gtest. The gtest docs recommend building gtest individually for
-// each program rather than using an installed gtest and this is as
-// easy a way of doing it as any. Especially because it guarantees that
-// the compiler flags are the same, which is the whole point of the
-// recommendation to build gtest for each program.
-
-// the .. goes back from the include/ directory of gtest so we can
-// enter the src directory.
-#include <../src/gtest-all.cc>
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+
+// Includes a file from gtest that pulls in all of the implementation
+// of gtest. The gtest docs recommend building gtest individually for
+// each program rather than using an installed gtest and this is as
+// easy a way of doing it as any. Especially because it guarantees that
+// the compiler flags are the same, which is the whole point of the
+// recommendation to build gtest for each program.
+
+namespace mgb {}
+using namespace mgb;
+
+// the .. goes back from the include/ directory of gtest so we can
+// enter the src directory.
+#include <../src/gtest-all.cc>
diff --git a/src/test/ideals.cpp b/src/test/ideals.cpp
index cb87fdd..92882e7 100755
--- a/src/test/ideals.cpp
+++ b/src/test/ideals.cpp
@@ -1,340 +1,339 @@
-#include "mathicgb/stdinc.h"
-#include "test/ideals.hpp"
-
-#include <sstream>
-
-std::string smallIdealComponentLastDescending() {
-  return 
-    "32003 6\n"
-    "1 1 1 1 1 1 1\n"
-    "_revlex revcomponent\n"
-    "3\n"
-    "-bc+ad\n"
-    "-b2+af\n"
-    "-bc2+a2e\n";
-}
-
-const char* idealSmallBasis = "\
-0 <0>  bc-ad\n\
-1 <1>  b2-af\n\
-2 <2>  bc2-a2e\n\
-3 c<0>  acd-a2e\n\
-4 b<0>  abd-acf\n\
-5 c2<1>  a2be-ac2f\n\
-6 bc<0>  a2d2-ac2f\n\
-7 c3<1>  a3de-ac3f\n\
-8 c4<1>  a4e2-ac4f\n\
-";
-
-const char* idealSmallSyzygies =
-  "  0: b2  bc2  \n  1: c2d  bc2  \n";
-
-const char* idealSmallInitial =
-  "  bc\n  b2\n  acd\n  abd\n  a2be\n  a2d2\n  a3de\n  a4e2\n";
-
-std::string liuIdealComponentLastDescending() {
-  return 
-    "2 6\n"
-    "1 1 1 1 1 1 1\n"
-    "_revlex revcomponent\n"
-    "4\n"
-    "bc+bd+af+ef\n"
-    "ac+cd+bf+ef\n"
-    "ad+bd+cf+ef\n"
-    "ab+ac+df+ef\n";
-}
-
-const char* liu_gb_strat0_free1 = 
-"\
-0 <0>  bc+bd+af+ef\n\
-1 <1>  ac+cd+bf+ef\n\
-2 <2>  ad+bd+cf+ef\n\
-3 <3>  ab+ac+df+ef\n\
-4 c<2>  bd2+cd2+c2f+cef+cf2+ef2\n\
-5 b<2>  b2d+cd2+d2f+bef+af2+ef2\n\
-6 b<1>  c2d+cd2+b2f+c2f+cdf+bef+cef+def+af2+ef2\n\
-7 a<0>  a2f+b2f+c2f+d2f+aef+bef+cef+def\n\
-8 ad<0>  cd2f+d3f+cdef+d2ef+b2f2+c2f2+bdf2+aef2+def2+e2f2+bf3+ef3\n\
-9 c2<2>  c3f+d3f+c2ef+bdef+cdef+d2ef+b2f2+c2f2+d2f2+aef2+bef2+e2f2+af3+bf3\n\
-10 b2<1>  b3f+d3f+b2ef+d2ef+b2f2+c2f2+bef2+cef2+bf3+df3\n\
-11 c2d<2>  b2ef2+d2ef2+be2f2+de2f2+b2f3+d2f3+aef3+cef3+af4+bf4+cf4+df4\n\
-12 c2d2<2>  bde2f2+cde2f2+c2ef3+d2ef3+ae2f3+e3f3+c2f4+bdf4+cdf4+d2f4+aef4+def4+df5+ef5\n\
-13 c2d3<2>  c2e2f3+d2e2f3+ce3f3+de3f3+c2ef4+d2ef4+be2f4+ce2f4+aef5+cef5+af6+bf6+cf6+df6\n\
-14 c2d4<2>  cde2f4+d2e2f4+ae3f4+be3f4+ce3f4+e4f4+ce2f5+e3f5+cdf6+d2f6+aef6+bef6+cef6+e2f6+cf7+ef7\n\
-15 c2d5<2>  d2e3f4+de4f4+ae3f5+be3f5+d2ef6+be2f6+aef7+bef7+bf8+df8\n\
-";
-
-const char* liu_syzygies_strat0_free1 =
-  "  0: ac  ab  a2d  \n  1: ab  b2d  b2c  \n  2: bc  ac  ab  c3d  \n";
-
-const char* liu_initial_strat0_free1 =
-  "  ad\n  bc\n  ac\n  ab\n  a2f\n  bd2\n  c2d\n  b2d\n  cd2f\n  c3f\n  b3f\n  b2ef2\n  bde2f2\n  c2e2f3\n  cde2f4\n  d2e3f4\n";
-
-std::string weispfennig97IdealComponentLast(bool componentsAscending) {
-  std::ostringstream out;
-  out << "7583 4 schreyer revlex 1\n";
-  if (componentsAscending)
-    out << "1 1 1 1 _revlex component\n";
-  else
-    out << "1 1 1 1 _revlex revcomponent\n";
-  out <<
-    "3\n"
-    "b4+ab2c+a2d2-2abd2+b2d2+c2d2 \n"
-    "a2b2c-bc4+a3d2+ab2d2+ac2d2+3d5 \n"
-    "a3b2-abc3+a2d3+b2d3+c2d3\n";
-  return out.str();
-}
-
-
-const char* weispfennig97_gb_strat0_free4 = "\
-0 <0>  b4+ab2c+a2d2-2abd2+b2d2+c2d2\n\
-1 <1>  a2b2c-bc4+a3d2+ab2d2+ac2d2+3d5\n\
-2 <2>  a3b2-abc3+a2d3+b2d3+c2d3\n\
-3 c<2>  a4d2+a2b2d2+a2c2d2-a2cd3-b2cd3-c3d3+3ad5\n\
-4 b2<1>  b3c4+abc5-2a3bcd2-ab2c2d2-abc3d2+bc4d2-2a2bd4+a2d5-2b2d5-3acd5+c2d5-3d7\n\
-5 b2<2>  ab3c3+a2bc4+2a2b3d2+2a2bc2d2-a2b2d3-2a2bcd3+ab2cd3-2b3cd3-b2c2d3-2bc3d3-2a2d5+4abd5+b2d5+c2d5\n\
-6 b3<1>  ab3c2d2+ab2c3d2+a2c4d2+c6d2+2a2b2d4-a2bd5+2b3d5-2a2cd5+3abcd5-2b2cd5-bc2d5-2c3d5+3bd7\n\
-7 b2c<2>  a2bc3d2-abc4d2+bc5d2+ab2c2d3-b2c3d3-bc4d3+2a3bd4-a3cd4-ab2cd4-ac3d4+3ab2d5+a2cd5-2abcd5+b2cd5+c3d5+3ad7-3cd7+3d8\n\
-8 b3<2>  a3c3d2+ab2c3d2+ac5d2+a2b3d3-ab3cd3+b3c2d3-2a3d5+2a2bd5-b3d5-2ac2d5-bc2d5\n\
-9 ab2<2>  a3bc4+b2c6+a3bc2d2+3ab2c3d2+a2c4d2-abc4d2+c6d2-2a3bcd3-2ab3cd3-ab2c2d3-3abc3d3+bc4d3+2a2b2d4-3a3d5+a2bd5-2a2cd5+3abcd5-2b2cd5-6bc2d5-2c3d5+a2d6+b2d6+c2d6+3bd7-3d8\n\
-10 b3c<1>  a2bc4d2-ab2c4d2-a2c5d2-c7d2+2a2b3d4+2a2bc2d4-2bc4d4-a2b2d5-a2bcd5+ab2cd5-4b3cd5+2a2c2d5-3abc2d5+b2c2d5-bc3d5+2c4d5+2a3d6+2ab2d6+2ac2d6-2a2d7+4abd7+b2d7-3bcd7+c2d7+6d9\n\
-11 b2c2<2>  ab2c4d2+a2c5d2-abc5d2+bc6d2+c7d2+ab2c3d3-b2c4d3-bc5d3-2a2b3d4+2a3bcd4-a3c2d4-2a2bc2d4-ab2c2d4-ac4d4+2bc4d4+a2b2d5+a2bcd5+2ab2cd5+4b3cd5-a2c2d5+abc2d5+bc3d5-c4d5-2a3d6-2ab2d6-2ac2d6+2a2d7-4abd7-b2d7+3acd7+3bcd7-4c2d7+3cd8-6d9\n\
-12 ab3<1>  a3c4d2+b2c5d2+ac6d2+bc6d2-a3bcd4-ab3cd4-a3c2d4-ab2c2d4+abc3d4-ac4d4-a3bd5+2ab3d5-2a3cd5+3a2bcd5-2ab2cd5-abc2d5-2ac3d5-2a2d7+3abd7-2b2d7-3bcd7-5c2d7\n\
-13 b3c<2>  a2c5d2-abc5d2+b2c5d2+2bc6d2+c7d2-b3c3d3-a2c4d3-2b2c4d3-bc5d3-c6d3-2a2b3d4+a3bcd4-ab3cd4-2a3c2d4-2a2bc2d4-2ab2c2d4+abc3d4-2ac4d4+2bc4d4-a2b2d5+3ab3d5+2a2bcd5+5b3cd5-a2c2d5+abc2d5+2bc3d5-c4d5-2a3d6+a2bd6-2ab2d6-2b3d6+2a2cd6-3abcd6+2b2cd6-2ac2d6+bc2d6+2c3d6-abd7-3b2d7+3acd7-9c2d7+3cd8-6d9\n\
-14 a2b2<1>  a3bc5+b2c7+2b2c5d2-2a3bc2d3-2ab2c3d3-2b3c3d3-2abc4d3+2bc5d3+4a2b3d4-6a3bcd4-2ab3cd4+4a2bc2d4+2abc3d4-4a2b2d5+6ab3d5-3a3cd5+2a2bcd5-9ab2cd5-4b3cd5-a2c2d5+4abc2d5-2b2c2d5-7bc3d5-c4d5+a2cd6+b2cd6+c3d6-9a2d7+16abd7-3b2d7-6acd7-6bcd7-3c2d7-3ad8+6bd8-6cd8\n\
-15 ab3<2>  a3bd5-ac3d5-b3d6-abcd6+2ad8\n\
-16 ab2c2<2>  b2c6d2-bc7d2+abc5d3+b2c5d3-a3bc2d4+3ab2c3d4+a2c4d4+abc4d4+2b2c4d4-2bc5d4+c6d4-a2b3d5-2a3bcd5-ab3cd5-6ab2c2d5-3b3c2d5-abc3d5+2b2c3d5-2bc4d5+2a2b2d6-2ab3d6+2a3cd6+2ab2cd6-2abc2d6-4ac3d6+2a3d7-a2bd7-3ab2d7-5b3d7-7a2cd7+7abcd7-4b2cd7+2ac2d7-5bc2d7-c3d7+a2d8+b2d8-3acd8+c2d8+6ad9-3bd9+6cd9\n\
-17 a2b3<1>  abc6d2+bc7d2-2b2c5d3-bc6d3-ab2c3d4+b3c3d4+a2c4d4+2abc4d4-b2c4d4+c6d4+4a2b3d5+4a3bcd5+5ab3cd5+a3c2d5+2ab2c2d5+3b3c2d5-a2c3d5-abc3d5-b2c3d5-2ac4d5+3bc4d5-c5d5+2a2b2d6-ab3d6-a2bcd6+2ab2cd6-4b3cd6-abc2d6+2ac3d6-bc3d6-2a3d7-3ab2d7+5b3d7-a2cd7+2abcd7-4b2cd7-2ac2d7-7c3d7+2a2d8-b2d8+6acd8+3bcd8+5c2d8-4ad9+6bd9-3d10\n\
-18 a2b3<2>  a2b3d5+a2bc2d5+a2c3d5+ab3d6-b3cd6-bc3d6-2a2d8+3abd8\n\
-19 bc5<2>  a2bc6d2-ab2c6d2+b2c7d2+2abc5d4+2b2c5d4-4bc6d4-5ab2c3d5-2b3c3d5-a2c4d5+b2c4d5+4bc5d5-c6d5-4ab3cd6+3a3c2d6+a2bc2d6+6ab2c2d6+3b3c2d6-3abc3d6+b2c3d6-4ac4d6+2bc4d6+c5d6-3a2b2d7+4ab3d7-a3cd7-3a2bcd7-8ab2cd7-5b3cd7-6a2c2d7+5abc2d7-4b2c2d7-3ac3d7-bc3d7-3c4d7-3a3d8+3a2bd8-ab2d8-5b3d8+6a2cd8-11abcd8+3b2cd8-3ac2d8+3c3d8+a2d9-2abd9-b2d9+8acd9-9bcd9+11c2d9+ad10-15cd10\n\
-20 b3c3<1>  a2c7d2+b2c7d2+c9d2-4ab2c3d5+2b3c3d5-3a2c4d5+4abc4d5-2b2c4d5+3bc5d5-3c6d5-2ab3cd6-a3c2d6+a2bc2d6+ab2c2d6+3b3c2d6-abc3d6+2b2c3d6-2ac4d6+3bc4d6+c5d6-3a2b2d7+4ab3d7-a3cd7-3a2bcd7-2ab2cd7+b3cd7-2a2c2d7+3abc2d7-3b2c2d7-5ac3d7+2bc3d7-2c4d7-3a3d8+3a2bd8-4ab2d8-7b3d8+5a2cd8-11abcd8+2b2cd8-3ac2d8+2c3d8+a2d9-2abd9-b2d9+2acd9-3bcd9-c2d9+2ad10-9cd10-3d11\n\
-21 b3c3<2>  abc7d2-2bc8d2-abc5d4+2b2c5d4-3bc6d4+2a3bc2d5-7ab2c3d5-4b3c3d5-2a2c4d5+abc4d5-2b2c4d5+3bc5d5-2c6d5-3ab3cd6+3a3c2d6-a2bc2d6+12ab2c2d6+b3c2d6+2a2c3d6-2b2c3d6+3ac4d6+6ab3d7+2a3cd7-6a2bcd7-4ab2cd7+2b3cd7-4a2c2d7+9abc2d7-2b2c2d7+ac3d7+2bc3d7+5c4d7+a2bd8+2b3d8+9a2cd8-14abcd8+9b2cd8+6bc2d8+6c3d8-2a2d9-2abd9+2b2d9+3acd9-9bcd9+8c2d9-ad10+3bd10-15cd10+3d11\n\
-22 a2b3c<1>  bc8d2-bc7d3-2526abc5d4-b2c5d4+2531ab2c3d5+3b3c3d5+4b2c4d5-ac5d5-bc5d5+ab3cd6+a2bc2d6-6ab2c2d6-4b3c2d6-2528a2c3d6-2529abc3d6+2b2c3d6-2bc4d6-a2b2d7-2534ab3d7+a2bcd7+2530ab2cd7-2b3cd7+2529a2c2d7-6abc2d7+2527b2c2d7-5ac3d7-2bc3d7+2524c4d7+2a3d8-2ab2d8-7b3d8-5a2cd8+5abcd8-4b2cd8+4ac2d8-3bc2d8+c3d8+a2d9+abd9+2530b2d9-3acd9+6bcd9+2530c2d9+7ad10-12bd10+7cd10\n\
-23 a3b3<1>  a2c4d5+abc4d5+b2c4d5-bc5d5+ab3cd6-ab2c2d6-b3c2d6+b2c3d6-ab3d7+a3cd7+ab2cd7-abc2d7-2ac3d7-3ab2d8-3b3d8-3a2cd8+2abcd8-b2cd8-c3d8+3ad10-3bd10+3cd10-3d11\n\
-24 abc5<2>  abc8d2-2bc9d2+abc5d5-11b2c5d5-3bc6d5+12ab2c3d6+7b3c3d6-8abc4d6-11b2c4d6+2ac5d6+12bc5d6+7c6d6+12ab3cd7+8a3c2d7-9a2bc2d7+21ab2c2d7+19b3c2d7-8a2c3d7+3abc3d7-17b2c3d7+9ac4d7+16bc4d7+4c5d7+10a2b2d8-6ab3d8-14a3cd8-3a2bcd8-4ab2cd8+5b3cd8+7a2c2d8+9abc2d8+9b2c2d8+29ac3d8+bc3d8+4c4d8-4a3d9-20a2bd9+29ab2d9+63b3d9+23a2cd9-8abcd9-5ac2d9-4bc2d9-3c3d9+18a2d10-20abd10-3b2d10-11acd10+27bcd10+15c2d10-50ad11+48bd11-33cd11+3d12\n\
-25 ab3c3<2>  ac6d5+bc6d5+b3c3d6-b2c4d6-a3c2d7-ab2c2d7+2a2c3d7+ac4d7+3a2b2d8+2ab3d8+3ab2cd8+2b3cd8-2ac3d8-a2d10-acd10-3c2d10+3ad11\n\
-26 a3b3c<1>  abc5d5+3790bc6d5+3791c7d5-ab2c3d6-3790b2c4d6+3792bc5d6-3790a3c2d7-3790ab2c2d7-a2c3d7-abc3d7+3791ac4d7-bc4d7+3791a2b2d8+3789ab3d8-a2bcd8+3790ab2cd8+3788b3cd8-a2c2d8+3791b2c2d8+a3d9+ab2d9+ac2d9+2a2d10+3789abd10-3790b2d10+acd10+3790bcd10+6c2d10+3790bd11-3cd11+3d12\n\
-27 a2bc5<2>  bc10d2+2540bc7d5+2521b2c5d6-2535bc6d6-846c7d6+2511ab2c3d7+2523b3c3d7+2509abc4d7-17b2c4d7+3ac5d7+852bc5d7-2525c6d7+3ab3cd8+2534a3c2d8-2536a2bc2d8+2570ab2c2d8+2569b3c2d8+1669a2c3d8-3371abc3d8-2554b2c3d8-3372ac4d8-1668bc4d8-3c5d8-3357a2b2d9-841ab3d9-2548a3cd9+856a2bcd9+1663ab2cd9+1675b3cd9+2518a2c2d9+2566abc2d9+845b2c2d9-2473ac3d9+2538bc3d9+1688c4d9-3392a3d10-2530a2bd10-792ab2d10+85b3d10+40a2cd10+2517abcd10+2536b2cd10-3395ac2d10+2528bc2d10-2559c3d10-1654a2d11+793abd11-855b2d11- [...]
-28 a2b3c3<1>  ac7d5+bc7d5-b2c5d6+3790bc6d6+3791c7d6-ab2c3d7-2abc4d7+3791b2c4d7+2ac5d7-3789bc5d7-ab3cd8-3790a3c2d8-a2bc2d8-3784ab2c2d8+5b3c2d8-2a2c3d8-2b2c3d8+3791ac4d8+bc4d8+3791a2b2d9+3790ab3d9-2a3cd9-a2bcd9+3788ab2cd9+3791b3cd9-a2c2d9+4abc2d9+3791b2c2d9+4ac3d9+bc3d9-4a3d10+4a2bd10+4ab2d10+5b3d10+5a2cd10-4abcd10+2b2cd10-5ac2d10-bc2d10-c3d10+3a2d11+3786abd11-3788b2d11+3acd11+3790bcd11+5c2d11-6ad12-3787bd12-9cd12+3d13\n\
-29 a3b3c2<1>  bc7d5-3033c8d5-b2c5d6+3033bc6d6-3034ab2c3d7+3034abc4d7+3032b2c4d7+3034ac5d7+3034bc5d7-1515ab3cd8-3035a2bc2d8+1518ab2c2d8-1513b3c2d8+3031a2c3d8+1516b2c3d8+1518bc4d8-1517c5d8-ab3d9-3034a3cd9-3034ab2cd9-3031b3cd9-3032abc2d9-3032ac3d9-3031bc3d9+3031a3d10-1515a2bd10+3033ab2d10+3035b3d10+3034a2cd10+3033abcd10-b2cd10+1514ac2d10+1517bc2d10-4c3d10+1521a2d11-1522abd11+3032b2d11-1516bcd11-3032c2d11-3036ad12-1513bd12-1519cd12+1516d13\n\
-30 a3b3c3<1>  c9d5-3033c8d6-b2c5d7+3030bc6d7+2528c7d7-3032ab2c3d8+3b3c3d8+3040abc4d8+3036b2c4d8+3034ac5d8+507bc5d8-c6d8-1516ab3cd9+3a3c2d9-3035a2bc2d9+1520ab2c2d9-1512b3c2d9-2025a2c3d9+2527abc3d9+1517b2c3d9+2528ac4d9-1007bc4d9-1517c5d9+2523a2b2d10+2525ab3d10-3034a3cd10-2528a2bcd10-511ab2cd10-505b3cd10-2a2c2d10-3029abc2d10-2529b2c2d10-3043ac3d10-3028bc3d10+2526c4d10-2025a3d11-1516a2bd11-2031ab2d11+3025b3d11+3033a2cd11+3024abcd11-3542ac2d11+1514bc2d11-c3d11-1006a2d12+3533abd12-2023b2d12+25 [...]
-";
-
-const char* weispfennig97_syzygies_strat0_free4 =
-  "  1: b4  a4b3  \n  2: b4  a2b2c  a3b3  b3c4  a3bc5  \n";
-
-const char* weispfennig97_initial_strat0_free4 =
-  "  b4\n  a2b2c\n  a3b2\n  a4d2\n  b3c4\n  ab3c3\n  a2bc3d2\n  a3c3d2\n  ab3c2d2\n  a3bc4\n  a3bd5\n  a2c5d2\n  ab2c4d2\n  a2b3d5\n  b2c6d2\n  abc6d2\n  a2c4d5\n  bc8d2\n  ac6d5\n  abc5d5\n  bc7d5\n  c9d5\n";
-
-const char* weispfennig97_gb_strat0_free5 = "\
-0 <0>  b4+ab2c+a2d2-2abd2+b2d2+c2d2\n\
-1 <1>  a2b2c-bc4+a3d2+ab2d2+ac2d2+3d5\n\
-2 <2>  a3b2-abc3+a2d3+b2d3+c2d3\n\
-3 a<1>  a4d2+a2b2d2+a2c2d2-a2cd3-b2cd3-c3d3+3ad5\n\
-4 a2c<0>  b3c4+abc5-2a3bcd2-ab2c2d2-abc3d2+bc4d2-2a2bd4+a2d5-2b2d5-3acd5+c2d5-3d7\n\
-5 a3<0>  ab3c3+a2bc4+2a2b3d2+2a2bc2d2-a2b2d3-2a2bcd3+ab2cd3-2b3cd3-b2c2d3-2bc3d3-2a2d5+4abd5+b2d5+c2d5\n\
-6 a2bc<0>  ab3c2d2+ab2c3d2+a2c4d2+c6d2+2a2b2d4-a2bd5+2b3d5-2a2cd5+3abcd5-2b2cd5-bc2d5-2c3d5+3bd7\n\
-7 ab2<1>  a2bc3d2-abc4d2+bc5d2+ab2c2d3-b2c3d3-bc4d3+2a3bd4-a3cd4-ab2cd4-ac3d4+3ab2d5+a2cd5-2abcd5+b2cd5+c3d5+3ad7-3cd7+3d8\n\
-8 a3b<0>  a3c3d2+ab2c3d2+ac5d2+a2b3d3-ab3cd3+b3c2d3-2a3d5+2a2bd5-b3d5-2ac2d5-bc2d5\n\
-9 a4<0>  a3bc4+b2c6+a3bc2d2+3ab2c3d2+a2c4d2-abc4d2+c6d2-2a3bcd3-2ab3cd3-ab2c2d3-3abc3d3+bc4d3+2a2b2d4-3a3d5+a2bd5-2a2cd5+3abcd5-2b2cd5-6bc2d5-2c3d5+a2d6+b2d6+c2d6+3bd7-3d8\n\
-10 a2bc2<0>  a2bc4d2-ab2c4d2-a2c5d2-c7d2+2a2b3d4+2a2bc2d4-2bc4d4-a2b2d5-a2bcd5+ab2cd5-4b3cd5+2a2c2d5-3abc2d5+b2c2d5-bc3d5+2c4d5+2a3d6+2ab2d6+2ac2d6-2a2d7+4abd7+b2d7-3bcd7+c2d7+6d9\n\
-11 ab2c<1>  ab2c4d2+a2c5d2-abc5d2+bc6d2+c7d2+ab2c3d3-b2c4d3-bc5d3-2a2b3d4+2a3bcd4-a3c2d4-2a2bc2d4-ab2c2d4-ac4d4+2bc4d4+a2b2d5+a2bcd5+2ab2cd5+4b3cd5-a2c2d5+abc2d5+bc3d5-c4d5-2a3d6-2ab2d6-2ac2d6+2a2d7-4abd7-b2d7+3acd7+3bcd7-4c2d7+3cd8-6d9\n\
-12 ab3<1>  a2c5d2-abc5d2+b2c5d2+2bc6d2+c7d2-b3c3d3-a2c4d3-2b2c4d3-bc5d3-c6d3-2a2b3d4+a3bcd4-ab3cd4-2a3c2d4-2a2bc2d4-2ab2c2d4+abc3d4-2ac4d4+2bc4d4-a2b2d5+3ab3d5+2a2bcd5+5b3cd5-a2c2d5+abc2d5+2bc3d5-c4d5-2a3d6+a2bd6-2ab2d6-2b3d6+2a2cd6-3abcd6+2b2cd6-2ac2d6+bc2d6+2c3d6-abd7-3b2d7+3acd7-9c2d7+3cd8-6d9\n\
-13 a4b<0>  a3bd5-ac3d5-b3d6-abcd6+2ad8\n\
-14 a2b2c<1>  b2c6d2-bc7d2+abc5d3+b2c5d3-a3bc2d4+3ab2c3d4+a2c4d4+abc4d4+2b2c4d4-2bc5d4+c6d4-a2b3d5-2a3bcd5-ab3cd5-6ab2c2d5-3b3c2d5-abc3d5+2b2c3d5-2bc4d5+2a2b2d6-2ab3d6+2a3cd6+2ab2cd6-2abc2d6-4ac3d6+2a3d7-a2bd7-3ab2d7-5b3d7-7a2cd7+7abcd7-4b2cd7+2ac2d7-5bc2d7-c3d7+a2d8+b2d8-3acd8+c2d8+6ad9-3bd9+6cd9\n\
-15 a2b3<1>  abc6d2+bc7d2-2b2c5d3-bc6d3-ab2c3d4+b3c3d4+a2c4d4+2abc4d4-b2c4d4+c6d4+4a2b3d5+a3bcd5+5ab3cd5+a3c2d5+2ab2c2d5+3b3c2d5-a2c3d5-abc3d5-b2c3d5+ac4d5+3bc4d5-c5d5+2a2b2d6-ab3d6-a2bcd6+2ab2cd6-b3cd6+2abc2d6+2ac3d6-bc3d6-2a3d7-3ab2d7+5b3d7-a2cd7+2abcd7-4b2cd7-2ac2d7-7c3d7+2a2d8-b2d8+3bcd8+5c2d8-4ad9+6bd9-3d10\n\
-16 a5b<0>  a2b3d5+a2bc2d5+a2c3d5+ab3d6-b3cd6-bc3d6-2a2d8+3abd8\n\
-17 abc4<1>  a2bc6d2-ab2c6d2+b2c7d2+2abc5d4+2b2c5d4-4bc6d4-5ab2c3d5-2b3c3d5-a2c4d5+b2c4d5+4bc5d5-c6d5-4ab3cd6+3a3c2d6+a2bc2d6+6ab2c2d6+3b3c2d6-3abc3d6+b2c3d6-4ac4d6+2bc4d6+c5d6-3a2b2d7+4ab3d7-a3cd7-3a2bcd7-8ab2cd7-5b3cd7-6a2c2d7+5abc2d7-4b2c2d7-3ac3d7-bc3d7-3c4d7-3a3d8+3a2bd8-ab2d8-5b3d8+6a2cd8-11abcd8+3b2cd8-3ac2d8+3c3d8+a2d9-2abd9-b2d9+8acd9-9bcd9+11c2d9+ad10-15cd10\n\
-18 a2bc4<0>  a2c7d2+b2c7d2+c9d2-4ab2c3d5+2b3c3d5-3a2c4d5+4abc4d5-2b2c4d5+3bc5d5-3c6d5-2ab3cd6-a3c2d6+a2bc2d6+ab2c2d6+3b3c2d6-abc3d6+2b2c3d6-2ac4d6+3bc4d6+c5d6-3a2b2d7+4ab3d7-a3cd7-3a2bcd7-2ab2cd7+b3cd7-2a2c2d7+3abc2d7-3b2c2d7-5ac3d7+2bc3d7-2c4d7-3a3d8+3a2bd8-4ab2d8-7b3d8+5a2cd8-11abcd8+2b2cd8-3ac2d8+2c3d8+a2d9-2abd9-b2d9+2acd9-3bcd9-c2d9+2ad10-9cd10-3d11\n\
-19 ab3c2<1>  abc7d2-2bc8d2-abc5d4+2b2c5d4-3bc6d4+2a3bc2d5-7ab2c3d5-4b3c3d5-2a2c4d5+abc4d5-2b2c4d5+3bc5d5-2c6d5-3ab3cd6+3a3c2d6-a2bc2d6+12ab2c2d6+b3c2d6+2a2c3d6-2b2c3d6+3ac4d6+6ab3d7+2a3cd7-6a2bcd7-4ab2cd7+2b3cd7-4a2c2d7+9abc2d7-2b2c2d7+ac3d7+2bc3d7+5c4d7+a2bd8+2b3d8+9a2cd8-14abcd8+9b2cd8+6bc2d8+6c3d8-2a2d9-2abd9+2b2d9+3acd9-9bcd9+8c2d9-ad10+3bd10-15cd10+3d11\n\
-20 a2b3c<1>  bc8d2-bc7d3-2526abc5d4-b2c5d4-a3bc2d5+2531ab2c3d5+3b3c3d5+4b2c4d5-bc5d5+ab3cd6+a2bc2d6-6ab2c2d6-3b3c2d6-2528a2c3d6-2528abc3d6+2b2c3d6-2bc4d6-a2b2d7-2534ab3d7+a2bcd7+2530ab2cd7-2b3cd7+2529a2c2d7-6abc2d7+2527b2c2d7-5ac3d7-2bc3d7+2524c4d7+2a3d8-2ab2d8-7b3d8-5a2cd8+5abcd8-4b2cd8+2ac2d8-3bc2d8+c3d8+a2d9+abd9+2530b2d9-3acd9+6bcd9+2530c2d9+7ad10-12bd10+7cd10\n\
-21 a5bc<0>  a2c4d5+abc4d5+b2c4d5-bc5d5+ab3cd6-ab2c2d6-b3c2d6+b2c3d6-ab3d7+a3cd7+ab2cd7-abc2d7-2ac3d7-3ab2d8-3b3d8-3a2cd8+2abcd8-b2cd8-c3d8+3ad10-3bd10+3cd10-3d11\n\
-22 a2bc4<1>  abc8d2-2bc9d2+abc5d5-11b2c5d5-3bc6d5+12ab2c3d6+7b3c3d6-8abc4d6-11b2c4d6+2ac5d6+12bc5d6+7c6d6+12ab3cd7+8a3c2d7-9a2bc2d7+21ab2c2d7+19b3c2d7-8a2c3d7+3abc3d7-17b2c3d7+9ac4d7+16bc4d7+4c5d7+10a2b2d8-6ab3d8-14a3cd8-3a2bcd8-4ab2cd8+5b3cd8+7a2c2d8+9abc2d8+9b2c2d8+29ac3d8+bc3d8+4c4d8-4a3d9-20a2bd9+29ab2d9+63b3d9+23a2cd9-8abcd9-5ac2d9-4bc2d9-3c3d9+18a2d10-20abd10-3b2d10-11acd10+27bcd10+15c2d10-50ad11+48bd11-33cd11+3d12\n\
-23 a4bc3<0>  ac6d5+bc6d5+b3c3d6-b2c4d6-a3c2d7-ab2c2d7+2a2c3d7+ac4d7+3a2b2d8+2ab3d8+3ab2cd8+2b3cd8-2ac3d8-a2d10-acd10-3c2d10+3ad11\n\
-24 a5bc2<0>  abc5d5+3790bc6d5+3791c7d5-ab2c3d6-3790b2c4d6+3792bc5d6-3790a3c2d7-3790ab2c2d7-a2c3d7-abc3d7+3791ac4d7-bc4d7+3791a2b2d8+3789ab3d8-a2bcd8+3790ab2cd8+3788b3cd8-a2c2d8+3791b2c2d8+a3d9+ab2d9+ac2d9+2a2d10+3789abd10-3790b2d10+acd10+3790bcd10+6c2d10+3790bd11-3cd11+3d12\n\
-25 a3bc4<1>  bc10d2+2540bc7d5+2521b2c5d6-2535bc6d6-846c7d6+2511ab2c3d7+2523b3c3d7+2509abc4d7-17b2c4d7+3ac5d7+852bc5d7-2525c6d7+3ab3cd8+2534a3c2d8-2536a2bc2d8+2570ab2c2d8+2569b3c2d8+1669a2c3d8-3371abc3d8-2554b2c3d8-3372ac4d8-1668bc4d8-3c5d8-3357a2b2d9-841ab3d9-2548a3cd9+856a2bcd9+1663ab2cd9+1675b3cd9+2518a2c2d9+2566abc2d9+845b2c2d9-2473ac3d9+2538bc3d9+1688c4d9-3392a3d10-2530a2bd10-792ab2d10+85b3d10+40a2cd10+2517abcd10+2536b2cd10-3395ac2d10+2528bc2d10-2559c3d10-1654a2d11+793abd11-855b2d11- [...]
-26 a5bc3<0>  bc7d5-3033c8d5-b2c5d6+3033bc6d6-3034ab2c3d7+3034abc4d7+3032b2c4d7+3034ac5d7+3034bc5d7-1515ab3cd8-3035a2bc2d8+1518ab2c2d8-1513b3c2d8+3031a2c3d8+1516b2c3d8+1518bc4d8-1517c5d8-ab3d9-3034a3cd9-3034ab2cd9-3031b3cd9-3032abc2d9-3032ac3d9-3031bc3d9+3031a3d10-1515a2bd10+3033ab2d10+3035b3d10+3034a2cd10+3033abcd10-b2cd10+1514ac2d10+1517bc2d10-4c3d10+1521a2d11-1522abd11+3032b2d11-1516bcd11-3032c2d11-3036ad12-1513bd12-1519cd12+1516d13\n\
-27 a5bc4<0>  c9d5-3033c8d6-b2c5d7+3030bc6d7+2528c7d7-3032ab2c3d8+3b3c3d8+3040abc4d8+3036b2c4d8+3034ac5d8+507bc5d8-c6d8-1516ab3cd9+3a3c2d9-3035a2bc2d9+1520ab2c2d9-1512b3c2d9-2025a2c3d9+2527abc3d9+1517b2c3d9+2528ac4d9-1007bc4d9-1517c5d9+2523a2b2d10+2525ab3d10-3034a3cd10-2528a2bcd10-511ab2cd10-505b3cd10-2a2c2d10-3029abc2d10-2529b2c2d10-3043ac3d10-3028bc3d10+2526c4d10-2025a3d11-1516a2bd11-2031ab2d11+3025b3d11+3033a2cd11+3024abcd11-3542ac2d11+1514bc2d11-c3d11-1006a2d12+3533abd12-2023b2d12+252 [...]
-";
-
-const char* weispfennig97_syzygies_strat0_free5 =
-  "  0: a2b2c  a3b2  a6b  \n  1: ab4  a3b2  ab3c3  a4bc4  \n";
-
-const char* weispfennig97_initial_strat0_free5 =
-  "  b4\n  a2b2c\n  a3b2\n  a4d2\n  b3c4\n  ab3c3\n  a2bc3d2\n  a3c3d2\n  ab3c2d2\n  a3bc4\n  a3bd5\n  a2c5d2\n  ab2c4d2\n  a2b3d5\n  b2c6d2\n  abc6d2\n  a2c4d5\n  bc8d2\n  ac6d5\n  abc5d5\n  bc7d5\n  c9d5\n";
-
-const char* Gert93RawIdeal = 
-  "3\n"
-  "ab-b2-4bc+ae\n"
-  "a2c-6bc2+a2f\n"
-  "a3+b2c-a2d\n";
-
-
-std::string gerdt93IdealComponentLast(bool componentsAscending, bool schreyer) {
-  std::ostringstream out;
-  out << "7583 6\n";
-  if (schreyer)
-    out << "schreyer ";
-  out << "revlex 1\n";
-  if (componentsAscending)
-    out << " 1 1 1 1 1 1 _revlex component\n";
-  else
-    out << " 1 1 1 1 1 1 _revlex revcomponent\n";
-  out << Gert93RawIdeal;
-  return out.str();
-}
-
-std::string gerdt93IdealComponentFirst(bool componentsAscending) {
-  std::ostringstream out;
-  out << "7583 6 schreyer revlex 2\n";
-  if (componentsAscending)
-    out << " component\n 1 1 1 1 1 1\n";
-  else
-    out << " revcomponent\n 1 1 1 1 1 1\n";
-  out << Gert93RawIdeal;
-  return out.str();
-}
-
-std::string gerdt93IdealComponentMiddle(bool componentsAscending) {
-  std::ostringstream out;
-  out << "7583 6 schreyer revlex 2\n";
-  if (componentsAscending)
-    out << "1 1 1 1 1 1\n component\n";
-  else
-    out << "1 1 1 1 1 1\n revcomponent\n";
-  out << Gert93RawIdeal;
-  return out.str();
-}
-
-const char* gerdt93_gb_strat0_free1 = "\
-0 <0>  ab-b2-4bc+ae\n\
-1 <1>  a2c-6bc2+a2f\n\
-2 <2>  a3+b2c-a2d\n\
-3 a<1>  abc2+1264b2c2-bc2d+1264b2cf\n\
-4 c2<0>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
-5 ac<0>  b3c+3259bc3+1085bc2d-b2ce+1081ac2e-10bc2e+ace2+b3f+1091b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
-6 a2<1>  b3c2-216b2c3-12b2c2d+36bc2d2-6ab2cf+b3cf+216b2c2f-6b2cdf-36a2bf2\n\
-7 a2<0>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
-8 bc2<0>  bc4-563bc3d-2577bc2d2-1896ac3e-469bc3e-2229ac2de+3088bc2de+2013ac2e2-1829bc3f-3362b2cdf-2179bc2df+3088b2cef+2353ac2ef+3515bc2ef-1075ace2f-785b3f2+2930b2cf2+2606bc2f2-348a2ef2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
-9 ac2<0>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
-10 ac3<0>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
-";
-
-const char* gerdt93_syzygies_strat0_free1 = "\
-  0: a2c  a3  b2c2  abc2  \n\
-  1: a3  \n\
-";
-
-const char* gerdt93_initial_strat0_free1 =
-  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
-
-const char* gerdt93_gb_strat0_free2 = "\
-0 <0>  ab-b2-4bc+ae\n\
-1 <1>  a2c-6bc2+a2f\n\
-2 <2>  a3+b2c-a2d\n\
-3 b<1>  b3c+2b2c2+16bc3-b2ce-4ac2e-10bc2e+ace2+b3f+8b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
-4 c<2>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
-5 b<2>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
-6 bc<2>  bc4-563bc3d-2577bc2d2-1896ac3e-2681bc3e-2577ac2de-3362bc2de+3088ac2e2-1829bc3f-3362b2cdf-2179bc2df-3362b2cef+2353ac2ef+1659bc2ef-1133ace2f-785b3f2+2930b2cf2+2606bc2f2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
-7 ac<2>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
-8 ac2<2>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
-";
-
-const char* gerdt93_syzygies_strat0_free2 = "\
-  1: ab  \n\
-  2: ab  b2c  a2c  \n\
-";
-
-const char* gerdt93_initial_strat0_free2 =
-  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
-
-const char* gerdt93_gb_strat0_free3 = "\
-0 <0>  ab-b2-4bc+ae\n\
-1 <1>  a2c-6bc2+a2f\n\
-2 <2>  a3+b2c-a2d\n\
-3 a<1>  abc2+1264b2c2-bc2d+1264b2cf\n\
-4 c2<0>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
-5 ac<0>  b3c+3259bc3+1085bc2d-b2ce+1081ac2e-10bc2e+ace2+b3f+1091b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
-6 a2<0>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
-7 a2<1>  b3c2-216b2c3-12b2c2d+36bc2d2-6ab2cf+b3cf+216b2c2f-6b2cdf-36a2bf2\n\
-8 bc2<0>  bc4-563bc3d-2577bc2d2-1896ac3e-469bc3e-2229ac2de+3088bc2de+2013ac2e2-1829bc3f-3362b2cdf-2179bc2df+3088b2cef+2353ac2ef+3515bc2ef-1075ace2f-785b3f2+2930b2cf2+2606bc2f2-348a2ef2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
-9 ac2<0>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
-10 ac3<0>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
-";
-
-const char* gerdt93_syzygies_strat0_free3 = "\
-  0: a2c  a3  b2c2  abc2  \n\
-  1: a3  \n\
-";
-
-const char* gerdt93_initial_strat0_free3 =
-  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
-
-const char* gerdt93_gb_strat0_free4 = "\
-0 <0>  ab-b2-4bc+ae\n\
-1 <1>  a2c-6bc2+a2f\n\
-2 <2>  a3+b2c-a2d\n\
-3 b<1>  b3c+2b2c2+16bc3-b2ce-4ac2e-10bc2e+ace2+b3f+8b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
-4 c<2>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
-5 b<2>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
-6 bc<2>  bc4-563bc3d-2577bc2d2-1896ac3e-2681bc3e-2577ac2de-3362bc2de+3088ac2e2-1829bc3f-3362b2cdf-2179bc2df-3362b2cef+2353ac2ef+1659bc2ef-1133ace2f-785b3f2+2930b2cf2+2606bc2f2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
-7 ac<2>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
-8 ac2<2>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
-";
-
-const char* gerdt93_syzygies_strat0_free4 = "\
-  1: ab  \n\
-  2: ab  b2c  a2c  \n\
-";
-
-const char* gerdt93_initial_strat0_free4 =
-  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
-
-const char* gerdt93_gb_strat0_free5 = "\
-0 <0>  ab-b2-4bc+ae\n\
-1 <1>  a2c-6bc2+a2f\n\
-2 <2>  a3+b2c-a2d\n\
-3 ac<0>  b3c+2b2c2+16bc3-b2ce-4ac2e-10bc2e+ace2+b3f+8b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
-4 a<1>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
-5 a2<0>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
-6 ab<1>  bc4-563bc3d-2577bc2d2-1896ac3e-2681bc3e-2577ac2de-3362bc2de+3088ac2e2-1829bc3f-3362b2cdf-2179bc2df-3362b2cef+2353ac2ef+1659bc2ef-1133ace2f-785b3f2+2930b2cf2+2606bc2f2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
-7 a2<1>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
-8 a2c<1>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
-";
-
-const char* gerdt93_syzygies_strat0_free5 = "\
-  0: a2c  a3  \n\
-  1: ab2  a2b  a3  \n\
-";
-const char* gerdt93_initial_strat0_free5 =
-  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
-
-const char* gerdt93_gb_strat0_free6 = "0 <0>  ab-b2-4bc+ae\n1 <1>  a2c-6bc2+a2f\n2 <2>  a3+b2c-a2d\n3 b<1>  b3c+2b2c2+16bc3-b2ce-4ac2e-10bc2e+ace2+b3f+8b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n4 c<2>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n5 b<2>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n6 bc<2>  bc4-563bc3d-2577bc2d2-1896ac3e-2681bc3e-2577ac2de-3362bc2de+3088ac2e2-1829b [...]
-const char* gerdt93_syzygies_strat0_free6 =
-  "  1: ab  \n  2: ab  b2c  a2c  \n";
-const char* gerdt93_initial_strat0_free6 =
-  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
-
-const char* gerdt93_gb_strat0_free7 = "\
-0 <0>  ab-b2-4bc+ae\n\
-1 <1>  a2c-6bc2+a2f\n\
-2 <2>  a3+b2c-a2d\n\
-3 a<1>  abc2+1264b2c2-bc2d+1264b2cf\n\
-4 a2<1>  b3c2-216b2c3-12b2c2d+36bc2d2-6ab2cf+b3cf+216b2c2f-6b2cdf-36a2bf2\n\
-5 c2<0>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
-6 ac<0>  b3c+3259bc3+1085bc2d-b2ce+1081ac2e-10bc2e+ace2+b3f+1091b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
-7 a2<0>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
-8 bc2<0>  bc4-563bc3d-2577bc2d2-1896ac3e-469bc3e-2229ac2de+3088bc2de+2013ac2e2-1829bc3f-3362b2cdf-2179bc2df+3088b2cef+2353ac2ef+3515bc2ef-1075ace2f-785b3f2+2930b2cf2+2606bc2f2-348a2ef2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
-9 ac2<0>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
-10 ac3<0>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
-";
-
-const char* gerdt93_syzygies_strat0_free7 =
-  "  0: a2c  a3  b2c2  abc2  \n  1: a3  \n";
-const char* gerdt93_initial_strat0_free7 =
-  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+#include "test/ideals.hpp"
+
+#include <sstream>
+
+using namespace mgb;
+
+std::string smallIdealComponentLastDescending() {
+  return 
+    "32003 6\n"
+    "1 1 1 1 1 1 1\n"
+    "_revlex revcomponent\n"
+    "3\n"
+    "-bc+ad\n"
+    "-b2+af\n"
+    "-bc2+a2e\n";
+}
+
+const char* idealSmallBasis = "\
+0 <0>  bc-ad\n\
+1 <1>  b2-af\n\
+2 <2>  bc2-a2e\n\
+3 c<0>  acd-a2e\n\
+4 b<0>  abd-acf\n\
+5 c2<1>  a2be-ac2f\n\
+6 bc<0>  a2d2-ac2f\n\
+7 c3<1>  a3de-ac3f\n\
+8 c4<1>  a4e2-ac4f\n\
+";
+
+const char* idealSmallSyzygies =
+  "  0: b2  bc2  \n  1: c2d  bc2  \n";
+
+const char* idealSmallInitial =
+  "  bc\n  b2\n  acd\n  abd\n  a2be\n  a2d2\n  a3de\n  a4e2\n";
+
+std::string liuIdealComponentLastDescending() {
+  return 
+    "2 6\n"
+    "1 1 1 1 1 1 1\n"
+    "_revlex revcomponent\n"
+    "4\n"
+    "bc+bd+af+ef\n"
+    "ac+cd+bf+ef\n"
+    "ad+bd+cf+ef\n"
+    "ab+ac+df+ef\n";
+}
+
+const char* liu_gb_strat0_free1 = 
+"\
+0 <0>  bc+bd+af+ef\n\
+1 <1>  ac+cd+bf+ef\n\
+2 <2>  ad+bd+cf+ef\n\
+3 <3>  ab+ac+df+ef\n\
+4 c<2>  bd2+cd2+c2f+cef+cf2+ef2\n\
+5 b<2>  b2d+cd2+d2f+bef+af2+ef2\n\
+6 b<1>  c2d+cd2+b2f+c2f+cdf+bef+cef+def+af2+ef2\n\
+7 a<0>  a2f+b2f+c2f+d2f+aef+bef+cef+def\n\
+8 ad<0>  cd2f+d3f+cdef+d2ef+b2f2+c2f2+bdf2+aef2+def2+e2f2+bf3+ef3\n\
+9 c2<2>  c3f+d3f+c2ef+bdef+cdef+d2ef+b2f2+c2f2+d2f2+aef2+bef2+e2f2+af3+bf3\n\
+10 b2<1>  b3f+d3f+b2ef+d2ef+b2f2+c2f2+bef2+cef2+bf3+df3\n\
+11 c2d<2>  b2ef2+d2ef2+be2f2+de2f2+b2f3+d2f3+aef3+cef3+af4+bf4+cf4+df4\n\
+12 c2d2<2>  bde2f2+cde2f2+c2ef3+d2ef3+ae2f3+e3f3+c2f4+bdf4+cdf4+d2f4+aef4+def4+df5+ef5\n\
+13 c2d3<2>  c2e2f3+d2e2f3+ce3f3+de3f3+c2ef4+d2ef4+be2f4+ce2f4+aef5+cef5+af6+bf6+cf6+df6\n\
+14 c2d4<2>  cde2f4+d2e2f4+ae3f4+be3f4+ce3f4+e4f4+ce2f5+e3f5+cdf6+d2f6+aef6+bef6+cef6+e2f6+cf7+ef7\n\
+15 c2d5<2>  d2e3f4+de4f4+ae3f5+be3f5+d2ef6+be2f6+aef7+bef7+bf8+df8\n\
+";
+
+const char* liu_syzygies_strat0_free1 =
+  "  0: ac  ab  a2d  \n  1: ab  b2d  b2c  \n  2: bc  ac  ab  c3d  \n";
+
+const char* liu_initial_strat0_free1 =
+  "  ad\n  bc\n  ac\n  ab\n  a2f\n  bd2\n  c2d\n  b2d\n  cd2f\n  c3f\n  b3f\n  b2ef2\n  bde2f2\n  c2e2f3\n  cde2f4\n  d2e3f4\n";
+
+std::string weispfennig97IdealComponentLast(bool componentsAscending) {
+  std::ostringstream out;
+  out << "7583 4 schreyer revlex 1\n";
+  if (componentsAscending)
+    out << "1 1 1 1 _revlex component\n";
+  else
+    out << "1 1 1 1 _revlex revcomponent\n";
+  out <<
+    "3\n"
+    "b4+ab2c+a2d2-2abd2+b2d2+c2d2 \n"
+    "a2b2c-bc4+a3d2+ab2d2+ac2d2+3d5 \n"
+    "a3b2-abc3+a2d3+b2d3+c2d3\n";
+  return out.str();
+}
+
+
+const char* weispfennig97_gb_strat0_free4 = "\
+0 <0>  b4+ab2c+a2d2-2abd2+b2d2+c2d2\n\
+1 <1>  a2b2c-bc4+a3d2+ab2d2+ac2d2+3d5\n\
+2 <2>  a3b2-abc3+a2d3+b2d3+c2d3\n\
+3 c<2>  a4d2+a2b2d2+a2c2d2-a2cd3-b2cd3-c3d3+3ad5\n\
+4 b2<1>  b3c4+abc5-2a3bcd2-ab2c2d2-abc3d2+bc4d2-2a2bd4+a2d5-2b2d5-3acd5+c2d5-3d7\n\
+5 b2<2>  ab3c3+a2bc4+2a2b3d2+2a2bc2d2-a2b2d3-2a2bcd3+ab2cd3-2b3cd3-b2c2d3-2bc3d3-2a2d5+4abd5+b2d5+c2d5\n\
+6 b3<1>  ab3c2d2+ab2c3d2+a2c4d2+c6d2+2a2b2d4-a2bd5+2b3d5-2a2cd5+3abcd5-2b2cd5-bc2d5-2c3d5+3bd7\n\
+7 b2c<2>  a2bc3d2-abc4d2+bc5d2+ab2c2d3-b2c3d3-bc4d3+2a3bd4-a3cd4-ab2cd4-ac3d4+3ab2d5+a2cd5-2abcd5+b2cd5+c3d5+3ad7-3cd7+3d8\n\
+8 b3<2>  a3c3d2+ab2c3d2+ac5d2+a2b3d3-ab3cd3+b3c2d3-2a3d5+2a2bd5-b3d5-2ac2d5-bc2d5\n\
+9 ab2<2>  a3bc4+b2c6+a3bc2d2+3ab2c3d2+a2c4d2-abc4d2+c6d2-2a3bcd3-2ab3cd3-ab2c2d3-3abc3d3+bc4d3+2a2b2d4-3a3d5+a2bd5-2a2cd5+3abcd5-2b2cd5-6bc2d5-2c3d5+a2d6+b2d6+c2d6+3bd7-3d8\n\
+10 b3c<1>  a2bc4d2-ab2c4d2-a2c5d2-c7d2+2a2b3d4+2a2bc2d4-2bc4d4-a2b2d5-a2bcd5+ab2cd5-4b3cd5+2a2c2d5-3abc2d5+b2c2d5-bc3d5+2c4d5+2a3d6+2ab2d6+2ac2d6-2a2d7+4abd7+b2d7-3bcd7+c2d7+6d9\n\
+11 b2c2<2>  ab2c4d2+a2c5d2-abc5d2+bc6d2+c7d2+ab2c3d3-b2c4d3-bc5d3-2a2b3d4+2a3bcd4-a3c2d4-2a2bc2d4-ab2c2d4-ac4d4+2bc4d4+a2b2d5+a2bcd5+2ab2cd5+4b3cd5-a2c2d5+abc2d5+bc3d5-c4d5-2a3d6-2ab2d6-2ac2d6+2a2d7-4abd7-b2d7+3acd7+3bcd7-4c2d7+3cd8-6d9\n\
+12 ab3<1>  a3c4d2+b2c5d2+ac6d2+bc6d2-a3bcd4-ab3cd4-a3c2d4-ab2c2d4+abc3d4-ac4d4-a3bd5+2ab3d5-2a3cd5+3a2bcd5-2ab2cd5-abc2d5-2ac3d5-2a2d7+3abd7-2b2d7-3bcd7-5c2d7\n\
+13 b3c<2>  a2c5d2-abc5d2+b2c5d2+2bc6d2+c7d2-b3c3d3-a2c4d3-2b2c4d3-bc5d3-c6d3-2a2b3d4+a3bcd4-ab3cd4-2a3c2d4-2a2bc2d4-2ab2c2d4+abc3d4-2ac4d4+2bc4d4-a2b2d5+3ab3d5+2a2bcd5+5b3cd5-a2c2d5+abc2d5+2bc3d5-c4d5-2a3d6+a2bd6-2ab2d6-2b3d6+2a2cd6-3abcd6+2b2cd6-2ac2d6+bc2d6+2c3d6-abd7-3b2d7+3acd7-9c2d7+3cd8-6d9\n\
+14 a2b2<1>  a3bc5+b2c7+2b2c5d2-2a3bc2d3-2ab2c3d3-2b3c3d3-2abc4d3+2bc5d3+4a2b3d4-6a3bcd4-2ab3cd4+4a2bc2d4+2abc3d4-4a2b2d5+6ab3d5-3a3cd5+2a2bcd5-9ab2cd5-4b3cd5-a2c2d5+4abc2d5-2b2c2d5-7bc3d5-c4d5+a2cd6+b2cd6+c3d6-9a2d7+16abd7-3b2d7-6acd7-6bcd7-3c2d7-3ad8+6bd8-6cd8\n\
+15 ab3<2>  a3bd5-ac3d5-b3d6-abcd6+2ad8\n\
+16 ab2c2<2>  b2c6d2-bc7d2+abc5d3+b2c5d3-a3bc2d4+3ab2c3d4+a2c4d4+abc4d4+2b2c4d4-2bc5d4+c6d4-a2b3d5-2a3bcd5-ab3cd5-6ab2c2d5-3b3c2d5-abc3d5+2b2c3d5-2bc4d5+2a2b2d6-2ab3d6+2a3cd6+2ab2cd6-2abc2d6-4ac3d6+2a3d7-a2bd7-3ab2d7-5b3d7-7a2cd7+7abcd7-4b2cd7+2ac2d7-5bc2d7-c3d7+a2d8+b2d8-3acd8+c2d8+6ad9-3bd9+6cd9\n\
+17 a2b3<1>  abc6d2+bc7d2-2b2c5d3-bc6d3-ab2c3d4+b3c3d4+a2c4d4+2abc4d4-b2c4d4+c6d4+4a2b3d5+4a3bcd5+5ab3cd5+a3c2d5+2ab2c2d5+3b3c2d5-a2c3d5-abc3d5-b2c3d5-2ac4d5+3bc4d5-c5d5+2a2b2d6-ab3d6-a2bcd6+2ab2cd6-4b3cd6-abc2d6+2ac3d6-bc3d6-2a3d7-3ab2d7+5b3d7-a2cd7+2abcd7-4b2cd7-2ac2d7-7c3d7+2a2d8-b2d8+6acd8+3bcd8+5c2d8-4ad9+6bd9-3d10\n\
+18 a2b3<2>  a2b3d5+a2bc2d5+a2c3d5+ab3d6-b3cd6-bc3d6-2a2d8+3abd8\n\
+19 bc5<2>  a2bc6d2-ab2c6d2+b2c7d2+2abc5d4+2b2c5d4-4bc6d4-5ab2c3d5-2b3c3d5-a2c4d5+b2c4d5+4bc5d5-c6d5-4ab3cd6+3a3c2d6+a2bc2d6+6ab2c2d6+3b3c2d6-3abc3d6+b2c3d6-4ac4d6+2bc4d6+c5d6-3a2b2d7+4ab3d7-a3cd7-3a2bcd7-8ab2cd7-5b3cd7-6a2c2d7+5abc2d7-4b2c2d7-3ac3d7-bc3d7-3c4d7-3a3d8+3a2bd8-ab2d8-5b3d8+6a2cd8-11abcd8+3b2cd8-3ac2d8+3c3d8+a2d9-2abd9-b2d9+8acd9-9bcd9+11c2d9+ad10-15cd10\n\
+20 b3c3<1>  a2c7d2+b2c7d2+c9d2-4ab2c3d5+2b3c3d5-3a2c4d5+4abc4d5-2b2c4d5+3bc5d5-3c6d5-2ab3cd6-a3c2d6+a2bc2d6+ab2c2d6+3b3c2d6-abc3d6+2b2c3d6-2ac4d6+3bc4d6+c5d6-3a2b2d7+4ab3d7-a3cd7-3a2bcd7-2ab2cd7+b3cd7-2a2c2d7+3abc2d7-3b2c2d7-5ac3d7+2bc3d7-2c4d7-3a3d8+3a2bd8-4ab2d8-7b3d8+5a2cd8-11abcd8+2b2cd8-3ac2d8+2c3d8+a2d9-2abd9-b2d9+2acd9-3bcd9-c2d9+2ad10-9cd10-3d11\n\
+21 b3c3<2>  abc7d2-2bc8d2-abc5d4+2b2c5d4-3bc6d4+2a3bc2d5-7ab2c3d5-4b3c3d5-2a2c4d5+abc4d5-2b2c4d5+3bc5d5-2c6d5-3ab3cd6+3a3c2d6-a2bc2d6+12ab2c2d6+b3c2d6+2a2c3d6-2b2c3d6+3ac4d6+6ab3d7+2a3cd7-6a2bcd7-4ab2cd7+2b3cd7-4a2c2d7+9abc2d7-2b2c2d7+ac3d7+2bc3d7+5c4d7+a2bd8+2b3d8+9a2cd8-14abcd8+9b2cd8+6bc2d8+6c3d8-2a2d9-2abd9+2b2d9+3acd9-9bcd9+8c2d9-ad10+3bd10-15cd10+3d11\n\
+22 a2b3c<1>  bc8d2-bc7d3-2526abc5d4-b2c5d4+2531ab2c3d5+3b3c3d5+4b2c4d5-ac5d5-bc5d5+ab3cd6+a2bc2d6-6ab2c2d6-4b3c2d6-2528a2c3d6-2529abc3d6+2b2c3d6-2bc4d6-a2b2d7-2534ab3d7+a2bcd7+2530ab2cd7-2b3cd7+2529a2c2d7-6abc2d7+2527b2c2d7-5ac3d7-2bc3d7+2524c4d7+2a3d8-2ab2d8-7b3d8-5a2cd8+5abcd8-4b2cd8+4ac2d8-3bc2d8+c3d8+a2d9+abd9+2530b2d9-3acd9+6bcd9+2530c2d9+7ad10-12bd10+7cd10\n\
+23 a3b3<1>  a2c4d5+abc4d5+b2c4d5-bc5d5+ab3cd6-ab2c2d6-b3c2d6+b2c3d6-ab3d7+a3cd7+ab2cd7-abc2d7-2ac3d7-3ab2d8-3b3d8-3a2cd8+2abcd8-b2cd8-c3d8+3ad10-3bd10+3cd10-3d11\n\
+24 abc5<2>  abc8d2-2bc9d2+abc5d5-11b2c5d5-3bc6d5+12ab2c3d6+7b3c3d6-8abc4d6-11b2c4d6+2ac5d6+12bc5d6+7c6d6+12ab3cd7+8a3c2d7-9a2bc2d7+21ab2c2d7+19b3c2d7-8a2c3d7+3abc3d7-17b2c3d7+9ac4d7+16bc4d7+4c5d7+10a2b2d8-6ab3d8-14a3cd8-3a2bcd8-4ab2cd8+5b3cd8+7a2c2d8+9abc2d8+9b2c2d8+29ac3d8+bc3d8+4c4d8-4a3d9-20a2bd9+29ab2d9+63b3d9+23a2cd9-8abcd9-5ac2d9-4bc2d9-3c3d9+18a2d10-20abd10-3b2d10-11acd10+27bcd10+15c2d10-50ad11+48bd11-33cd11+3d12\n\
+25 ab3c3<2>  ac6d5+bc6d5+b3c3d6-b2c4d6-a3c2d7-ab2c2d7+2a2c3d7+ac4d7+3a2b2d8+2ab3d8+3ab2cd8+2b3cd8-2ac3d8-a2d10-acd10-3c2d10+3ad11\n\
+26 a3b3c<1>  abc5d5+3790bc6d5+3791c7d5-ab2c3d6-3790b2c4d6+3792bc5d6-3790a3c2d7-3790ab2c2d7-a2c3d7-abc3d7+3791ac4d7-bc4d7+3791a2b2d8+3789ab3d8-a2bcd8+3790ab2cd8+3788b3cd8-a2c2d8+3791b2c2d8+a3d9+ab2d9+ac2d9+2a2d10+3789abd10-3790b2d10+acd10+3790bcd10+6c2d10+3790bd11-3cd11+3d12\n\
+27 a2bc5<2>  bc10d2+2540bc7d5+2521b2c5d6-2535bc6d6-846c7d6+2511ab2c3d7+2523b3c3d7+2509abc4d7-17b2c4d7+3ac5d7+852bc5d7-2525c6d7+3ab3cd8+2534a3c2d8-2536a2bc2d8+2570ab2c2d8+2569b3c2d8+1669a2c3d8-3371abc3d8-2554b2c3d8-3372ac4d8-1668bc4d8-3c5d8-3357a2b2d9-841ab3d9-2548a3cd9+856a2bcd9+1663ab2cd9+1675b3cd9+2518a2c2d9+2566abc2d9+845b2c2d9-2473ac3d9+2538bc3d9+1688c4d9-3392a3d10-2530a2bd10-792ab2d10+85b3d10+40a2cd10+2517abcd10+2536b2cd10-3395ac2d10+2528bc2d10-2559c3d10-1654a2d11+793abd11-855b2d11- [...]
+28 a2b3c3<1>  ac7d5+bc7d5-b2c5d6+3790bc6d6+3791c7d6-ab2c3d7-2abc4d7+3791b2c4d7+2ac5d7-3789bc5d7-ab3cd8-3790a3c2d8-a2bc2d8-3784ab2c2d8+5b3c2d8-2a2c3d8-2b2c3d8+3791ac4d8+bc4d8+3791a2b2d9+3790ab3d9-2a3cd9-a2bcd9+3788ab2cd9+3791b3cd9-a2c2d9+4abc2d9+3791b2c2d9+4ac3d9+bc3d9-4a3d10+4a2bd10+4ab2d10+5b3d10+5a2cd10-4abcd10+2b2cd10-5ac2d10-bc2d10-c3d10+3a2d11+3786abd11-3788b2d11+3acd11+3790bcd11+5c2d11-6ad12-3787bd12-9cd12+3d13\n\
+29 a3b3c2<1>  bc7d5-3033c8d5-b2c5d6+3033bc6d6-3034ab2c3d7+3034abc4d7+3032b2c4d7+3034ac5d7+3034bc5d7-1515ab3cd8-3035a2bc2d8+1518ab2c2d8-1513b3c2d8+3031a2c3d8+1516b2c3d8+1518bc4d8-1517c5d8-ab3d9-3034a3cd9-3034ab2cd9-3031b3cd9-3032abc2d9-3032ac3d9-3031bc3d9+3031a3d10-1515a2bd10+3033ab2d10+3035b3d10+3034a2cd10+3033abcd10-b2cd10+1514ac2d10+1517bc2d10-4c3d10+1521a2d11-1522abd11+3032b2d11-1516bcd11-3032c2d11-3036ad12-1513bd12-1519cd12+1516d13\n\
+30 a3b3c3<1>  c9d5-3033c8d6-b2c5d7+3030bc6d7+2528c7d7-3032ab2c3d8+3b3c3d8+3040abc4d8+3036b2c4d8+3034ac5d8+507bc5d8-c6d8-1516ab3cd9+3a3c2d9-3035a2bc2d9+1520ab2c2d9-1512b3c2d9-2025a2c3d9+2527abc3d9+1517b2c3d9+2528ac4d9-1007bc4d9-1517c5d9+2523a2b2d10+2525ab3d10-3034a3cd10-2528a2bcd10-511ab2cd10-505b3cd10-2a2c2d10-3029abc2d10-2529b2c2d10-3043ac3d10-3028bc3d10+2526c4d10-2025a3d11-1516a2bd11-2031ab2d11+3025b3d11+3033a2cd11+3024abcd11-3542ac2d11+1514bc2d11-c3d11-1006a2d12+3533abd12-2023b2d12+25 [...]
+";
+
+const char* weispfennig97_syzygies_strat0_free4 =
+  "  1: b4  a4b3  \n  2: b4  a2b2c  a3b3  b3c4  a3bc5  \n";
+
+const char* weispfennig97_initial_strat0_free4 =
+  "  b4\n  a2b2c\n  a3b2\n  a4d2\n  b3c4\n  ab3c3\n  a2bc3d2\n  a3c3d2\n  ab3c2d2\n  a3bc4\n  a3bd5\n  a2c5d2\n  ab2c4d2\n  a2b3d5\n  b2c6d2\n  abc6d2\n  a2c4d5\n  bc8d2\n  ac6d5\n  abc5d5\n  bc7d5\n  c9d5\n";
+
+const char* weispfennig97_gb_strat0_free5 = "\
+0 <0>  b4+ab2c+a2d2-2abd2+b2d2+c2d2\n\
+1 <1>  a2b2c-bc4+a3d2+ab2d2+ac2d2+3d5\n\
+2 <2>  a3b2-abc3+a2d3+b2d3+c2d3\n\
+3 a<1>  a4d2+a2b2d2+a2c2d2-a2cd3-b2cd3-c3d3+3ad5\n\
+4 a2c<0>  b3c4+abc5-2a3bcd2-ab2c2d2-abc3d2+bc4d2-2a2bd4+a2d5-2b2d5-3acd5+c2d5-3d7\n\
+5 a3<0>  ab3c3+a2bc4+2a2b3d2+2a2bc2d2-a2b2d3-2a2bcd3+ab2cd3-2b3cd3-b2c2d3-2bc3d3-2a2d5+4abd5+b2d5+c2d5\n\
+6 a2bc<0>  ab3c2d2+ab2c3d2+a2c4d2+c6d2+2a2b2d4-a2bd5+2b3d5-2a2cd5+3abcd5-2b2cd5-bc2d5-2c3d5+3bd7\n\
+7 ab2<1>  a2bc3d2-abc4d2+bc5d2+ab2c2d3-b2c3d3-bc4d3+2a3bd4-a3cd4-ab2cd4-ac3d4+3ab2d5+a2cd5-2abcd5+b2cd5+c3d5+3ad7-3cd7+3d8\n\
+8 a3b<0>  a3c3d2+ab2c3d2+ac5d2+a2b3d3-ab3cd3+b3c2d3-2a3d5+2a2bd5-b3d5-2ac2d5-bc2d5\n\
+9 a4<0>  a3bc4+b2c6+a3bc2d2+3ab2c3d2+a2c4d2-abc4d2+c6d2-2a3bcd3-2ab3cd3-ab2c2d3-3abc3d3+bc4d3+2a2b2d4-3a3d5+a2bd5-2a2cd5+3abcd5-2b2cd5-6bc2d5-2c3d5+a2d6+b2d6+c2d6+3bd7-3d8\n\
+10 a2bc2<0>  a2bc4d2-ab2c4d2-a2c5d2-c7d2+2a2b3d4+2a2bc2d4-2bc4d4-a2b2d5-a2bcd5+ab2cd5-4b3cd5+2a2c2d5-3abc2d5+b2c2d5-bc3d5+2c4d5+2a3d6+2ab2d6+2ac2d6-2a2d7+4abd7+b2d7-3bcd7+c2d7+6d9\n\
+11 ab2c<1>  ab2c4d2+a2c5d2-abc5d2+bc6d2+c7d2+ab2c3d3-b2c4d3-bc5d3-2a2b3d4+2a3bcd4-a3c2d4-2a2bc2d4-ab2c2d4-ac4d4+2bc4d4+a2b2d5+a2bcd5+2ab2cd5+4b3cd5-a2c2d5+abc2d5+bc3d5-c4d5-2a3d6-2ab2d6-2ac2d6+2a2d7-4abd7-b2d7+3acd7+3bcd7-4c2d7+3cd8-6d9\n\
+12 ab3<1>  a2c5d2-abc5d2+b2c5d2+2bc6d2+c7d2-b3c3d3-a2c4d3-2b2c4d3-bc5d3-c6d3-2a2b3d4+a3bcd4-ab3cd4-2a3c2d4-2a2bc2d4-2ab2c2d4+abc3d4-2ac4d4+2bc4d4-a2b2d5+3ab3d5+2a2bcd5+5b3cd5-a2c2d5+abc2d5+2bc3d5-c4d5-2a3d6+a2bd6-2ab2d6-2b3d6+2a2cd6-3abcd6+2b2cd6-2ac2d6+bc2d6+2c3d6-abd7-3b2d7+3acd7-9c2d7+3cd8-6d9\n\
+13 a4b<0>  a3bd5-ac3d5-b3d6-abcd6+2ad8\n\
+14 a2b2c<1>  b2c6d2-bc7d2+abc5d3+b2c5d3-a3bc2d4+3ab2c3d4+a2c4d4+abc4d4+2b2c4d4-2bc5d4+c6d4-a2b3d5-2a3bcd5-ab3cd5-6ab2c2d5-3b3c2d5-abc3d5+2b2c3d5-2bc4d5+2a2b2d6-2ab3d6+2a3cd6+2ab2cd6-2abc2d6-4ac3d6+2a3d7-a2bd7-3ab2d7-5b3d7-7a2cd7+7abcd7-4b2cd7+2ac2d7-5bc2d7-c3d7+a2d8+b2d8-3acd8+c2d8+6ad9-3bd9+6cd9\n\
+15 a2b3<1>  abc6d2+bc7d2-2b2c5d3-bc6d3-ab2c3d4+b3c3d4+a2c4d4+2abc4d4-b2c4d4+c6d4+4a2b3d5+a3bcd5+5ab3cd5+a3c2d5+2ab2c2d5+3b3c2d5-a2c3d5-abc3d5-b2c3d5+ac4d5+3bc4d5-c5d5+2a2b2d6-ab3d6-a2bcd6+2ab2cd6-b3cd6+2abc2d6+2ac3d6-bc3d6-2a3d7-3ab2d7+5b3d7-a2cd7+2abcd7-4b2cd7-2ac2d7-7c3d7+2a2d8-b2d8+3bcd8+5c2d8-4ad9+6bd9-3d10\n\
+16 a5b<0>  a2b3d5+a2bc2d5+a2c3d5+ab3d6-b3cd6-bc3d6-2a2d8+3abd8\n\
+17 abc4<1>  a2bc6d2-ab2c6d2+b2c7d2+2abc5d4+2b2c5d4-4bc6d4-5ab2c3d5-2b3c3d5-a2c4d5+b2c4d5+4bc5d5-c6d5-4ab3cd6+3a3c2d6+a2bc2d6+6ab2c2d6+3b3c2d6-3abc3d6+b2c3d6-4ac4d6+2bc4d6+c5d6-3a2b2d7+4ab3d7-a3cd7-3a2bcd7-8ab2cd7-5b3cd7-6a2c2d7+5abc2d7-4b2c2d7-3ac3d7-bc3d7-3c4d7-3a3d8+3a2bd8-ab2d8-5b3d8+6a2cd8-11abcd8+3b2cd8-3ac2d8+3c3d8+a2d9-2abd9-b2d9+8acd9-9bcd9+11c2d9+ad10-15cd10\n\
+18 a2bc4<0>  a2c7d2+b2c7d2+c9d2-4ab2c3d5+2b3c3d5-3a2c4d5+4abc4d5-2b2c4d5+3bc5d5-3c6d5-2ab3cd6-a3c2d6+a2bc2d6+ab2c2d6+3b3c2d6-abc3d6+2b2c3d6-2ac4d6+3bc4d6+c5d6-3a2b2d7+4ab3d7-a3cd7-3a2bcd7-2ab2cd7+b3cd7-2a2c2d7+3abc2d7-3b2c2d7-5ac3d7+2bc3d7-2c4d7-3a3d8+3a2bd8-4ab2d8-7b3d8+5a2cd8-11abcd8+2b2cd8-3ac2d8+2c3d8+a2d9-2abd9-b2d9+2acd9-3bcd9-c2d9+2ad10-9cd10-3d11\n\
+19 ab3c2<1>  abc7d2-2bc8d2-abc5d4+2b2c5d4-3bc6d4+2a3bc2d5-7ab2c3d5-4b3c3d5-2a2c4d5+abc4d5-2b2c4d5+3bc5d5-2c6d5-3ab3cd6+3a3c2d6-a2bc2d6+12ab2c2d6+b3c2d6+2a2c3d6-2b2c3d6+3ac4d6+6ab3d7+2a3cd7-6a2bcd7-4ab2cd7+2b3cd7-4a2c2d7+9abc2d7-2b2c2d7+ac3d7+2bc3d7+5c4d7+a2bd8+2b3d8+9a2cd8-14abcd8+9b2cd8+6bc2d8+6c3d8-2a2d9-2abd9+2b2d9+3acd9-9bcd9+8c2d9-ad10+3bd10-15cd10+3d11\n\
+20 a2b3c<1>  bc8d2-bc7d3-2526abc5d4-b2c5d4-a3bc2d5+2531ab2c3d5+3b3c3d5+4b2c4d5-bc5d5+ab3cd6+a2bc2d6-6ab2c2d6-3b3c2d6-2528a2c3d6-2528abc3d6+2b2c3d6-2bc4d6-a2b2d7-2534ab3d7+a2bcd7+2530ab2cd7-2b3cd7+2529a2c2d7-6abc2d7+2527b2c2d7-5ac3d7-2bc3d7+2524c4d7+2a3d8-2ab2d8-7b3d8-5a2cd8+5abcd8-4b2cd8+2ac2d8-3bc2d8+c3d8+a2d9+abd9+2530b2d9-3acd9+6bcd9+2530c2d9+7ad10-12bd10+7cd10\n\
+21 a5bc<0>  a2c4d5+abc4d5+b2c4d5-bc5d5+ab3cd6-ab2c2d6-b3c2d6+b2c3d6-ab3d7+a3cd7+ab2cd7-abc2d7-2ac3d7-3ab2d8-3b3d8-3a2cd8+2abcd8-b2cd8-c3d8+3ad10-3bd10+3cd10-3d11\n\
+22 a2bc4<1>  abc8d2-2bc9d2+abc5d5-11b2c5d5-3bc6d5+12ab2c3d6+7b3c3d6-8abc4d6-11b2c4d6+2ac5d6+12bc5d6+7c6d6+12ab3cd7+8a3c2d7-9a2bc2d7+21ab2c2d7+19b3c2d7-8a2c3d7+3abc3d7-17b2c3d7+9ac4d7+16bc4d7+4c5d7+10a2b2d8-6ab3d8-14a3cd8-3a2bcd8-4ab2cd8+5b3cd8+7a2c2d8+9abc2d8+9b2c2d8+29ac3d8+bc3d8+4c4d8-4a3d9-20a2bd9+29ab2d9+63b3d9+23a2cd9-8abcd9-5ac2d9-4bc2d9-3c3d9+18a2d10-20abd10-3b2d10-11acd10+27bcd10+15c2d10-50ad11+48bd11-33cd11+3d12\n\
+23 a4bc3<0>  ac6d5+bc6d5+b3c3d6-b2c4d6-a3c2d7-ab2c2d7+2a2c3d7+ac4d7+3a2b2d8+2ab3d8+3ab2cd8+2b3cd8-2ac3d8-a2d10-acd10-3c2d10+3ad11\n\
+24 a5bc2<0>  abc5d5+3790bc6d5+3791c7d5-ab2c3d6-3790b2c4d6+3792bc5d6-3790a3c2d7-3790ab2c2d7-a2c3d7-abc3d7+3791ac4d7-bc4d7+3791a2b2d8+3789ab3d8-a2bcd8+3790ab2cd8+3788b3cd8-a2c2d8+3791b2c2d8+a3d9+ab2d9+ac2d9+2a2d10+3789abd10-3790b2d10+acd10+3790bcd10+6c2d10+3790bd11-3cd11+3d12\n\
+25 a3bc4<1>  bc10d2+2540bc7d5+2521b2c5d6-2535bc6d6-846c7d6+2511ab2c3d7+2523b3c3d7+2509abc4d7-17b2c4d7+3ac5d7+852bc5d7-2525c6d7+3ab3cd8+2534a3c2d8-2536a2bc2d8+2570ab2c2d8+2569b3c2d8+1669a2c3d8-3371abc3d8-2554b2c3d8-3372ac4d8-1668bc4d8-3c5d8-3357a2b2d9-841ab3d9-2548a3cd9+856a2bcd9+1663ab2cd9+1675b3cd9+2518a2c2d9+2566abc2d9+845b2c2d9-2473ac3d9+2538bc3d9+1688c4d9-3392a3d10-2530a2bd10-792ab2d10+85b3d10+40a2cd10+2517abcd10+2536b2cd10-3395ac2d10+2528bc2d10-2559c3d10-1654a2d11+793abd11-855b2d11- [...]
+26 a5bc3<0>  bc7d5-3033c8d5-b2c5d6+3033bc6d6-3034ab2c3d7+3034abc4d7+3032b2c4d7+3034ac5d7+3034bc5d7-1515ab3cd8-3035a2bc2d8+1518ab2c2d8-1513b3c2d8+3031a2c3d8+1516b2c3d8+1518bc4d8-1517c5d8-ab3d9-3034a3cd9-3034ab2cd9-3031b3cd9-3032abc2d9-3032ac3d9-3031bc3d9+3031a3d10-1515a2bd10+3033ab2d10+3035b3d10+3034a2cd10+3033abcd10-b2cd10+1514ac2d10+1517bc2d10-4c3d10+1521a2d11-1522abd11+3032b2d11-1516bcd11-3032c2d11-3036ad12-1513bd12-1519cd12+1516d13\n\
+27 a5bc4<0>  c9d5-3033c8d6-b2c5d7+3030bc6d7+2528c7d7-3032ab2c3d8+3b3c3d8+3040abc4d8+3036b2c4d8+3034ac5d8+507bc5d8-c6d8-1516ab3cd9+3a3c2d9-3035a2bc2d9+1520ab2c2d9-1512b3c2d9-2025a2c3d9+2527abc3d9+1517b2c3d9+2528ac4d9-1007bc4d9-1517c5d9+2523a2b2d10+2525ab3d10-3034a3cd10-2528a2bcd10-511ab2cd10-505b3cd10-2a2c2d10-3029abc2d10-2529b2c2d10-3043ac3d10-3028bc3d10+2526c4d10-2025a3d11-1516a2bd11-2031ab2d11+3025b3d11+3033a2cd11+3024abcd11-3542ac2d11+1514bc2d11-c3d11-1006a2d12+3533abd12-2023b2d12+252 [...]
+";
+
+const char* weispfennig97_syzygies_strat0_free5 =
+  "  0: a2b2c  a3b2  a6b  \n  1: ab4  a3b2  ab3c3  a4bc4  \n";
+
+const char* weispfennig97_initial_strat0_free5 =
+  "  b4\n  a2b2c\n  a3b2\n  a4d2\n  b3c4\n  ab3c3\n  a2bc3d2\n  a3c3d2\n  ab3c2d2\n  a3bc4\n  a3bd5\n  a2c5d2\n  ab2c4d2\n  a2b3d5\n  b2c6d2\n  abc6d2\n  a2c4d5\n  bc8d2\n  ac6d5\n  abc5d5\n  bc7d5\n  c9d5\n";
+
+const char* Gert93RawIdeal = 
+  "3\n"
+  "ab-b2-4bc+ae\n"
+  "a2c-6bc2+a2f\n"
+  "a3+b2c-a2d\n";
+
+
+std::string gerdt93IdealComponentLast(bool componentsAscending, bool schreyer) {
+  std::ostringstream out;
+  out << "7583 6\n";
+  if (schreyer)
+    out << "schreyer ";
+  out << "revlex 1\n";
+  if (componentsAscending)
+    out << " 1 1 1 1 1 1 _revlex component\n";
+  else
+    out << " 1 1 1 1 1 1 _revlex revcomponent\n";
+  out << Gert93RawIdeal;
+  return out.str();
+}
+
+std::string gerdt93IdealComponentFirst(bool componentsAscending) {
+  std::ostringstream out;
+  out << "7583 6 schreyer revlex 2\n";
+  if (componentsAscending)
+    out << " component\n 1 1 1 1 1 1\n";
+  else
+    out << " revcomponent\n 1 1 1 1 1 1\n";
+  out << Gert93RawIdeal;
+  return out.str();
+}
+
+std::string gerdt93IdealComponentMiddle(bool componentsAscending) {
+  std::ostringstream out;
+  out << "7583 6 schreyer revlex 2\n";
+  if (componentsAscending)
+    out << "1 1 1 1 1 1\n component\n";
+  else
+    out << "1 1 1 1 1 1\n revcomponent\n";
+  out << Gert93RawIdeal;
+  return out.str();
+}
+
+const char* gerdt93_gb_strat0_free1 = "\
+0 <0>  ab-b2-4bc+ae\n\
+1 <1>  a2c-6bc2+a2f\n\
+2 <2>  a3+b2c-a2d\n\
+3 a<1>  abc2+1264b2c2-bc2d+1264b2cf\n\
+4 c2<0>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
+5 ac<0>  b3c+3259bc3+1085bc2d-b2ce+1081ac2e-10bc2e+ace2+b3f+1091b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
+6 a2<1>  b3c2-216b2c3-12b2c2d+36bc2d2-6ab2cf+b3cf+216b2c2f-6b2cdf-36a2bf2\n\
+7 a2<0>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
+8 bc2<0>  bc4-563bc3d-2577bc2d2-1896ac3e-469bc3e-2229ac2de+3088bc2de+2013ac2e2-1829bc3f-3362b2cdf-2179bc2df+3088b2cef+2353ac2ef+3515bc2ef-1075ace2f-785b3f2+2930b2cf2+2606bc2f2-348a2ef2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
+9 ac2<0>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
+10 ac3<0>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
+";
+
+const char* gerdt93_syzygies_strat0_free1 = "\
+  0: a2c  a3  b2c2  abc2  \n\
+  1: a3  \n\
+";
+
+const char* gerdt93_initial_strat0_free1 =
+  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
+
+const char* gerdt93_gb_strat0_free2 = "\
+0 <0>  ab-b2-4bc+ae\n\
+1 <1>  a2c-6bc2+a2f\n\
+2 <2>  a3+b2c-a2d\n\
+3 b<1>  b3c+2b2c2+16bc3-b2ce-4ac2e-10bc2e+ace2+b3f+8b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
+4 c<2>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
+5 b<2>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
+6 bc<2>  bc4-563bc3d-2577bc2d2-1896ac3e-2681bc3e-2577ac2de-3362bc2de+3088ac2e2-1829bc3f-3362b2cdf-2179bc2df-3362b2cef+2353ac2ef+1659bc2ef-1133ace2f-785b3f2+2930b2cf2+2606bc2f2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
+7 ac<2>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
+8 ac2<2>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
+";
+
+const char* gerdt93_syzygies_strat0_free2 = "\
+  1: ab  \n\
+  2: ab  b2c  a2c  \n\
+";
+
+const char* gerdt93_initial_strat0_free2 =
+  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
+
+const char* gerdt93_gb_strat0_free3 = "\
+0 <0>  ab-b2-4bc+ae\n\
+1 <1>  a2c-6bc2+a2f\n\
+2 <2>  a3+b2c-a2d\n\
+3 a<1>  abc2+1264b2c2-bc2d+1264b2cf\n\
+4 c2<0>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
+5 ac<0>  b3c+3259bc3+1085bc2d-b2ce+1081ac2e-10bc2e+ace2+b3f+1091b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
+6 a2<0>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
+7 a2<1>  b3c2-216b2c3-12b2c2d+36bc2d2-6ab2cf+b3cf+216b2c2f-6b2cdf-36a2bf2\n\
+8 bc2<0>  bc4-563bc3d-2577bc2d2-1896ac3e-469bc3e-2229ac2de+3088bc2de+2013ac2e2-1829bc3f-3362b2cdf-2179bc2df+3088b2cef+2353ac2ef+3515bc2ef-1075ace2f-785b3f2+2930b2cf2+2606bc2f2-348a2ef2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
+9 ac2<0>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
+10 ac3<0>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
+";
+
+const char* gerdt93_syzygies_strat0_free3 = "\
+  0: a2c  a3  b2c2  abc2  \n\
+  1: a3  \n\
+";
+
+const char* gerdt93_initial_strat0_free3 =
+  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
+
+const char* gerdt93_gb_strat0_free4 = "\
+0 <0>  ab-b2-4bc+ae\n\
+1 <1>  a2c-6bc2+a2f\n\
+2 <2>  a3+b2c-a2d\n\
+3 b<1>  b3c+2b2c2+16bc3-b2ce-4ac2e-10bc2e+ace2+b3f+8b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
+4 c<2>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
+5 b<2>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
+6 bc<2>  bc4-563bc3d-2577bc2d2-1896ac3e-2681bc3e-2577ac2de-3362bc2de+3088ac2e2-1829bc3f-3362b2cdf-2179bc2df-3362b2cef+2353ac2ef+1659bc2ef-1133ace2f-785b3f2+2930b2cf2+2606bc2f2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
+7 ac<2>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
+8 ac2<2>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
+";
+
+const char* gerdt93_syzygies_strat0_free4 = "\
+  1: ab  \n\
+  2: ab  b2c  a2c  \n\
+";
+
+const char* gerdt93_initial_strat0_free4 =
+  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
+
+const char* gerdt93_gb_strat0_free5 = "\
+0 <0>  ab-b2-4bc+ae\n\
+1 <1>  a2c-6bc2+a2f\n\
+2 <2>  a3+b2c-a2d\n\
+3 ac<0>  b3c+2b2c2+16bc3-b2ce-4ac2e-10bc2e+ace2+b3f+8b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
+4 a<1>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
+5 a2<0>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
+6 ab<1>  bc4-563bc3d-2577bc2d2-1896ac3e-2681bc3e-2577ac2de-3362bc2de+3088ac2e2-1829bc3f-3362b2cdf-2179bc2df-3362b2cef+2353ac2ef+1659bc2ef-1133ace2f-785b3f2+2930b2cf2+2606bc2f2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
+7 a2<1>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
+8 a2c<1>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
+";
+
+const char* gerdt93_syzygies_strat0_free5 = "\
+  0: a2c  a3  \n\
+  1: ab2  a2b  a3  \n\
+";
+const char* gerdt93_initial_strat0_free5 =
+  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
+
+const char* gerdt93_gb_strat0_free6 = "0 <0>  ab-b2-4bc+ae\n1 <1>  a2c-6bc2+a2f\n2 <2>  a3+b2c-a2d\n3 b<1>  b3c+2b2c2+16bc3-b2ce-4ac2e-10bc2e+ace2+b3f+8b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n4 c<2>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n5 b<2>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n6 bc<2>  bc4-563bc3d-2577bc2d2-1896ac3e-2681bc3e-2577ac2de-3362bc2de+3088ac2e2-1829b [...]
+const char* gerdt93_syzygies_strat0_free6 =
+  "  1: ab  \n  2: ab  b2c  a2c  \n";
+const char* gerdt93_initial_strat0_free6 =
+  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
+
+const char* gerdt93_gb_strat0_free7 = "\
+0 <0>  ab-b2-4bc+ae\n\
+1 <1>  a2c-6bc2+a2f\n\
+2 <2>  a3+b2c-a2d\n\
+3 a<1>  abc2+1264b2c2-bc2d+1264b2cf\n\
+4 a2<1>  b3c2-216b2c3-12b2c2d+36bc2d2-6ab2cf+b3cf+216b2c2f-6b2cdf-36a2bf2\n\
+5 c2<0>  b2c2+2170bc3+3249bc2d+3249ac2e+3250b2cf\n\
+6 ac<0>  b3c+3259bc3+1085bc2d-b2ce+1081ac2e-10bc2e+ace2+b3f+1091b2cf+16bc2f-b2ef-4acef-4bcef+ae2f\n\
+7 a2<0>  b4-2386bc3-b3d-8b2cd-3247bc2d-2b3e-6b2ce-3195ac2e+58bc2e+b2de+4acde+4bcde+a2e2+2b2e2-ace2+8bce2-ade2-2ae3-13b3f-3357b2cf-208bc2f+4a2ef+13b2ef+52acef+52bcef-13ae2f\n\
+8 bc2<0>  bc4-563bc3d-2577bc2d2-1896ac3e-469bc3e-2229ac2de+3088bc2de+2013ac2e2-1829bc3f-3362b2cdf-2179bc2df+3088b2cef+2353ac2ef+3515bc2ef-1075ace2f-785b3f2+2930b2cf2+2606bc2f2-348a2ef2+785b2ef2+3140acef2+3140bcef2-785ae2f2\n\
+9 ac2<0>  bc3e-3140ac2de-1718bc2de+2814ac2e2-1718b2cef+947bc2ef-3051ace2f+3140a2ef2\n\
+10 ac3<0>  ac3de+1155ac2d2e-2873bc2d2e+3790ac3e2-1570ac2de2+3362bc2de2-3088ac2e3+2814b2cdef+2370bc2def+3362b2ce2f-3790ac2e2f-1659bc2e2f-3599acde2f+1133ace3f-1896b3ef2-1898b2cef2-10bc2ef2-1155a2def2+2681a2e2f2+1896b2e2f2+ace2f2+bce2f2-1896ae3f2+a2ef3\n\
+";
+
+const char* gerdt93_syzygies_strat0_free7 =
+  "  0: a2c  a3  b2c2  abc2  \n  1: a3  \n";
+const char* gerdt93_initial_strat0_free7 =
+  "  ab\n  a2c\n  a3\n  b2c2\n  b3c\n  b4\n  bc3e\n  bc4\n  ac3de\n";
diff --git a/src/test/ideals.hpp b/src/test/ideals.hpp
index 4b0b709..a82c12e 100755
--- a/src/test/ideals.hpp
+++ b/src/test/ideals.hpp
@@ -1,67 +1,68 @@
-#ifndef _test_ideals_h_
-#define _test_ideals_h_
-
-// small
-std::string smallIdealComponentLastDescending();
-
-extern const char* idealSmallBasis;
-extern const char* idealSmallSyzygies;
-extern const char* idealSmallInitial;
-
-// liu
-std::string liuIdealComponentLastDescending();
-
-extern const char* liu_gb_strat0_free1;
-extern const char* liu_syzygies_strat0_free1;
-extern const char* liu_initial_strat0_free1;
-
-// weispfennig97
-std::string weispfennig97IdealComponentLast(bool componentsAscending);
-
-extern const char* weispfennig97_gb_strat0_free4;
-extern const char* weispfennig97_syzygies_strat0_free4;
-extern const char* weispfennig97_initial_strat0_free4;
-
-extern const char* weispfennig97_gb_strat0_free5;
-extern const char* weispfennig97_syzygies_strat0_free5;
-extern const char* weispfennig97_initial_strat0_free5;
-
-// gerdt93
-std::string gerdt93IdealComponentFirst(bool componentsAscending);
-std::string gerdt93IdealComponentMiddle(bool componentsAscending);
-std::string gerdt93IdealComponentLast(bool componentsAscending, bool schreyer);
-
-extern const char* gerdt93_gb_strat0_free1;
-extern const char* gerdt93_syzygies_strat0_free1;
-extern const char* gerdt93_initial_strat0_free1;
-
-extern const char* gerdt93_gb_strat0_free2;
-extern const char* gerdt93_syzygies_strat0_free2;
-extern const char* gerdt93_initial_strat0_free2;
-
-extern const char* gerdt93_gb_strat0_free3;
-extern const char* gerdt93_syzygies_strat0_free3;
-extern const char* gerdt93_initial_strat0_free3;
-
-extern const char* gerdt93_gb_strat0_free4;
-extern const char* gerdt93_syzygies_strat0_free4;
-extern const char* gerdt93_initial_strat0_free4;
-
-extern const char* gerdt93_gb_strat0_free5;
-extern const char* gerdt93_syzygies_strat0_free5;
-extern const char* gerdt93_initial_strat0_free5;
-
-extern const char* gerdt93_gb_strat0_free6;
-extern const char* gerdt93_syzygies_strat0_free6;
-extern const char* gerdt93_initial_strat0_free6;
-
-extern const char* gerdt93_gb_strat0_free7;
-extern const char* gerdt93_syzygies_strat0_free7;
-extern const char* gerdt93_initial_strat0_free7;
-
-#endif
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_IDEALS_GUARD
+#define MATHICGB_IDEALS_GUARD
+
+#include <string>
+
+namespace mgb {}
+
+// small
+std::string smallIdealComponentLastDescending();
+
+extern const char* idealSmallBasis;
+extern const char* idealSmallSyzygies;
+extern const char* idealSmallInitial;
+
+// liu
+std::string liuIdealComponentLastDescending();
+
+extern const char* liu_gb_strat0_free1;
+extern const char* liu_syzygies_strat0_free1;
+extern const char* liu_initial_strat0_free1;
+
+// weispfennig97
+std::string weispfennig97IdealComponentLast(bool componentsAscending);
+
+extern const char* weispfennig97_gb_strat0_free4;
+extern const char* weispfennig97_syzygies_strat0_free4;
+extern const char* weispfennig97_initial_strat0_free4;
+
+extern const char* weispfennig97_gb_strat0_free5;
+extern const char* weispfennig97_syzygies_strat0_free5;
+extern const char* weispfennig97_initial_strat0_free5;
+
+// gerdt93
+std::string gerdt93IdealComponentFirst(bool componentsAscending);
+std::string gerdt93IdealComponentMiddle(bool componentsAscending);
+std::string gerdt93IdealComponentLast(bool componentsAscending, bool schreyer);
+
+extern const char* gerdt93_gb_strat0_free1;
+extern const char* gerdt93_syzygies_strat0_free1;
+extern const char* gerdt93_initial_strat0_free1;
+
+extern const char* gerdt93_gb_strat0_free2;
+extern const char* gerdt93_syzygies_strat0_free2;
+extern const char* gerdt93_initial_strat0_free2;
+
+extern const char* gerdt93_gb_strat0_free3;
+extern const char* gerdt93_syzygies_strat0_free3;
+extern const char* gerdt93_initial_strat0_free3;
+
+extern const char* gerdt93_gb_strat0_free4;
+extern const char* gerdt93_syzygies_strat0_free4;
+extern const char* gerdt93_initial_strat0_free4;
+
+extern const char* gerdt93_gb_strat0_free5;
+extern const char* gerdt93_syzygies_strat0_free5;
+extern const char* gerdt93_initial_strat0_free5;
+
+extern const char* gerdt93_gb_strat0_free6;
+extern const char* gerdt93_syzygies_strat0_free6;
+extern const char* gerdt93_initial_strat0_free6;
+
+extern const char* gerdt93_gb_strat0_free7;
+extern const char* gerdt93_syzygies_strat0_free7;
+extern const char* gerdt93_initial_strat0_free7;
+
+#endif
diff --git a/src/test/mathicgb.cpp b/src/test/mathicgb.cpp
index 7f5ee90..f7381ed 100755
--- a/src/test/mathicgb.cpp
+++ b/src/test/mathicgb.cpp
@@ -1,557 +1,561 @@
-#include "mathicgb/stdinc.h"
-
-#include <gtest/gtest.h>
-#include "mathicgb.h"
-
-namespace {
-  template<class Stream>
-  void makeBasis(Stream& s) {
-    s.idealBegin();
-      s.appendPolynomialBegin(); // x^2 - y
-        s.appendTermBegin();
-          s.appendExponent(0,2);
-        s.appendTermDone(1);
-        s.appendTermBegin();
-          s.appendExponent(1,1);
-        s.appendTermDone(s.modulus() - 1);
-      s.appendPolynomialDone();
-      s.appendPolynomialBegin(2); // x^3-z
-        s.appendTermBegin();
-          s.appendExponent(0,3);
-        s.appendTermDone(1);
-        s.appendTermBegin();
-          s.appendExponent(2,1);
-        s.appendTermDone(s.modulus() - 1);
-      s.appendPolynomialDone();
-    s.idealDone();
-  }
-
-  template<class Stream>
-  void makeGroebnerBasis(Stream& s) {
-    s.idealBegin(3);
-      s.appendPolynomialBegin(2); // x^2 - y
-        s.appendTermBegin();
-          s.appendExponent(0, 2);
-          s.appendExponent(1, 0);
-          s.appendExponent(2, 0);
-        s.appendTermDone(1);
-        s.appendTermBegin();
-          s.appendExponent(0, 0);
-          s.appendExponent(1, 1);
-          s.appendExponent(2, 0);
-        s.appendTermDone(s.modulus() - 1);
-      s.appendPolynomialDone();
-      s.appendPolynomialBegin(2); // xy - z
-        s.appendTermBegin();
-          s.appendExponent(0, 1);
-          s.appendExponent(1, 1);
-          s.appendExponent(2, 0);
-        s.appendTermDone(1);
-        s.appendTermBegin();
-          s.appendExponent(0, 0);
-          s.appendExponent(1, 0);
-          s.appendExponent(2, 1);
-        s.appendTermDone(s.modulus() - 1);
-      s.appendPolynomialDone();
-      s.appendPolynomialBegin(2); // y^2 - xy
-        s.appendTermBegin();
-          s.appendExponent(0, 0);
-          s.appendExponent(1, 2);
-          s.appendExponent(2, 0);
-        s.appendTermDone(1);
-        s.appendTermBegin();
-          s.appendExponent(0, 1);
-          s.appendExponent(1, 0);
-          s.appendExponent(2, 1);
-        s.appendTermDone(s.modulus() - 1);
-      s.appendPolynomialDone();
-    s.idealDone();
-  }
-
-  template<class Stream>
-  void makeCyclic5Basis(Stream& s) {
-    s.idealBegin(5); // polyCount
-    s.appendPolynomialBegin(5);
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(1, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(2, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(3, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendPolynomialDone();
-    s.appendPolynomialBegin(5);
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(3, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendPolynomialDone();
-    s.appendPolynomialBegin(5);
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendPolynomialDone();
-    s.appendPolynomialBegin(5);
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendPolynomialDone();
-    s.appendPolynomialBegin(2);
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendExponent(4, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendTermDone(100); // coefficient
-    s.appendPolynomialDone();
-    s.idealDone();
-  }
-
-  template<class Stream>
-  void makeSimpleIdeal(Stream& s) { // variables a,b,c,d.  a2-bc, ab-cd.
-    s.idealBegin();
-      s.appendPolynomialBegin(); // a^2-b*c
-        s.appendTermBegin();
-          s.appendExponent(0,2);
-        s.appendTermDone(1);
-        s.appendTermBegin();
-          s.appendExponent(1,1);
-          s.appendExponent(2,1);
-        s.appendTermDone(s.modulus() - 1);
-      s.appendPolynomialDone();
-      s.appendPolynomialBegin(2); // a*b-c*d
-        s.appendTermBegin();
-          s.appendExponent(0,1);
-          s.appendExponent(1,1);
-        s.appendTermDone(1);
-        s.appendTermBegin();
-          s.appendExponent(2,1);
-          s.appendExponent(3,1);
-        s.appendTermDone(s.modulus() - 1);
-      s.appendPolynomialDone();
-    s.idealDone();
-  }
-
-  template<class Stream>
-  void makeSimpleIdealGroebnerBasis(Stream& s) { // variables a,b,c,d.  a2-bc, ab-cd.
-    // Groebner basis is {a^2-b*c,a*b-c*d,a*c*d-b^2*c,b^3*c-c^2*d^2}
-    // (order: eliminate 1 variable: [1 0 0 0; 1 1 1 1]).
-    s.idealBegin(4); // polyCount
-    s.appendPolynomialBegin(2);
-    s.appendTermBegin();
-    s.appendExponent(0, 2); // index, exponent
-    s.appendExponent(1, 0); // index, exponent
-    s.appendExponent(2, 0); // index, exponent
-    s.appendExponent(3, 0); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 0); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 0); // index, exponent
-    s.appendTermDone(100); // coefficient
-    s.appendPolynomialDone();
-    s.appendPolynomialBegin(2);
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 1); // index, exponent
-    s.appendExponent(2, 0); // index, exponent
-    s.appendExponent(3, 0); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 0); // index, exponent
-    s.appendExponent(1, 0); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendTermDone(100); // coefficient
-    s.appendPolynomialDone();
-    s.appendPolynomialBegin(2);
-    s.appendTermBegin();
-    s.appendExponent(0, 1); // index, exponent
-    s.appendExponent(1, 0); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 1); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 0); // index, exponent
-    s.appendExponent(1, 2); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 0); // index, exponent
-    s.appendTermDone(100); // coefficient
-    s.appendPolynomialDone();
-    s.appendPolynomialBegin(2);
-    s.appendTermBegin();
-    s.appendExponent(0, 0); // index, exponent
-    s.appendExponent(1, 3); // index, exponent
-    s.appendExponent(2, 1); // index, exponent
-    s.appendExponent(3, 0); // index, exponent
-    s.appendTermDone(1); // coefficient
-    s.appendTermBegin();
-    s.appendExponent(0, 0); // index, exponent
-    s.appendExponent(1, 0); // index, exponent
-    s.appendExponent(2, 2); // index, exponent
-    s.appendExponent(3, 2); // index, exponent
-    s.appendTermDone(100); // coefficient
-    s.appendPolynomialDone();
-    s.idealDone();
-  }
-}
-
-TEST(MathicGBLib, NullIdealStream) {
-  {
-    mgb::NullIdealStream stream(2, 3);
-    ASSERT_EQ(2, stream.modulus());
-    ASSERT_EQ(3, stream.varCount());
-    makeBasis(stream);
-  }
-
-  {
-    mgb::NullIdealStream stream(101, 0);
-    ASSERT_EQ(101, stream.modulus());
-    ASSERT_EQ(0, stream.varCount());
-  }
-}
-
-TEST(MathicGBLib, IdealStreamLog) {
-  {
-    const char* const idealStr = 
-      "s.idealBegin();\n"
-      "s.appendPolynomialBegin();\n"
-      "s.appendTermBegin();\n"
-      "s.appendExponent(0, 2); // index, exponent\n"
-      "s.appendTermDone(1); // coefficient\n"
-      "s.appendTermBegin();\n"
-      "s.appendExponent(1, 1); // index, exponent\n"
-      "s.appendTermDone(6); // coefficient\n"
-      "s.appendPolynomialDone();\n"
-      "s.appendPolynomialBegin(2);\n"
-      "s.appendTermBegin();\n"
-      "s.appendExponent(0, 3); // index, exponent\n"
-      "s.appendTermDone(1); // coefficient\n"
-      "s.appendTermBegin();\n"
-      "s.appendExponent(2, 1); // index, exponent\n"
-      "s.appendTermDone(6); // coefficient\n"
-      "s.appendPolynomialDone();\n"
-      "s.idealDone();\n";
-
-    std::ostringstream out1;
-    mgb::IdealStreamLog<> stream1(out1, 7, 3);
-
-    mgb::IdealStreamChecker<decltype(stream1)> checker(stream1);
-
-    std::ostringstream out2;
-    mgb::IdealStreamLog<decltype(checker)> stream2(out2, checker);
-
-    std::ostringstream out3;
-    mgb::IdealStreamLog<decltype(stream2)> stream3(out3, stream2);
-
-    ASSERT_EQ(7, stream1.modulus());
-    ASSERT_EQ(3, stream1.varCount());
-    ASSERT_EQ(7, checker.modulus());
-    ASSERT_EQ(3, checker.varCount());
-    ASSERT_EQ(7, stream2.modulus());
-    ASSERT_EQ(3, stream2.varCount());
-    ASSERT_EQ(7, stream3.modulus());
-    ASSERT_EQ(3, stream3.varCount());
-
-    makeBasis(stream3);
-    const auto str1 = std::string(
-      "IdealStreamLog s(stream, 7, 3);\n"
-    ) + idealStr;
-    ASSERT_EQ(str1, out1.str())
-      << "Displayed expected:\n" << out1.str()
-      << "Displayed actual:\n" << str1 << std::endl;
-
-    const auto str2 = std::string(
-      "IdealStreamLog s(stream, log); // modulus=7, varCount=3\n"
-    ) + idealStr;
-    ASSERT_EQ(str2, out2.str()) << "Displayed expected:\n" << out2.str();
-    ASSERT_EQ(str2, out3.str()) << "Displayed expected:\n" << out3.str();
-  }
-
-  // The ideal <> in no variables
-  {
-    std::ostringstream out;
-    mgb::IdealStreamLog<> stream(out, 101, 0);
-    ASSERT_EQ(101, stream.modulus());
-    ASSERT_EQ(0, stream.varCount());
-    stream.idealBegin(0);
-    stream.idealDone();
-  }
-
-  // The ideal <1, 0> in no variables
-  {
-    std::ostringstream out;
-    mgb::IdealStreamLog<> stream(out, 101, 0);
-    ASSERT_EQ(101, stream.modulus());
-    ASSERT_EQ(0, stream.varCount());
-    stream.idealBegin(2);
-      stream.appendPolynomialBegin(0); // 1
-        stream.appendTermBegin();
-        stream.appendTermDone(1);
-      stream.appendPolynomialDone();
-      stream.appendPolynomialBegin(0); // 0
-      stream.appendPolynomialDone();
-    stream.idealDone();
-  }
-}
-
-TEST(MathicGBLib, ZeroIdealGB) {
-  mgb::GroebnerConfiguration configuration(2, 0);
-  mgb::GroebnerInputIdealStream input(configuration);
-  std::ostringstream out;
-  mgb::IdealStreamLog<> logStream(out, 2, 0);
-
-  input.idealBegin(0);
-  input.idealDone();
-  mgb::computeGroebnerBasis(input, logStream);
-
-  const auto msg =
-    "IdealStreamLog s(stream, 2, 0);\n"
-    "s.idealBegin(0); // polyCount\n"
-    "s.idealDone();\n";
-  EXPECT_EQ(msg, out.str());
-}
-
-TEST(MathicGBLib, OneIdealGB) {
-  mgb::GroebnerConfiguration configuration(2, 0);
-  mgb::GroebnerInputIdealStream input(configuration);
-  std::ostringstream out;
-  mgb::IdealStreamLog<> logStream(out, 2, 0);
-
-  input.idealBegin(1);
-  input.appendPolynomialBegin(1);
-  input.appendTermBegin();
-  input.appendTermDone(1);
-  input.appendPolynomialDone();
-  input.idealDone();
-  mgb::computeGroebnerBasis(input, logStream);
-
-  const auto msg =
-     "IdealStreamLog s(stream, 2, 0);\n"
-     "s.idealBegin(1); // polyCount\n"
-     "s.appendPolynomialBegin(1);\n"
-     "s.appendTermBegin();\n"
-     "s.appendTermDone(1); // coefficient\n"
-     "s.appendPolynomialDone();\n"
-     "s.idealDone();\n";
-  EXPECT_EQ(msg, out.str());
-}
-
-TEST(MathicGBLib, EasyGB) {
-  mgb::GroebnerConfiguration configuration(101, 3);
-  mgb::GroebnerInputIdealStream input(configuration);
-  std::ostringstream computedStr;
-  mgb::IdealStreamLog<> computed(computedStr, 101, 3);
-  mgb::IdealStreamChecker<decltype(computed)> checked(computed);
-
-  makeBasis(input);
-  mgb::computeGroebnerBasis(input, checked);
-
-  std::ostringstream correctStr;
-  mgb::IdealStreamLog<> correct(correctStr, 101, 3);
-  mgb::IdealStreamChecker<decltype(correct)> correctChecked(correct);
-  makeGroebnerBasis(correctChecked);
-
-  EXPECT_EQ(correctStr.str(), computedStr.str())
-    << "\nDisplayed expected:\n" << correctStr.str()
-    << "\nDisplayed computed:\n" << computedStr.str();
-}
-
-TEST(MathicGBLib, EasyReGB) {
-  mgb::GroebnerConfiguration configuration(101, 3);
-  mgb::GroebnerInputIdealStream input(configuration);
-  std::ostringstream computedStr;
-  mgb::IdealStreamLog<> computed(computedStr, 101, 3);
-  mgb::IdealStreamChecker<decltype(computed)> checked(computed);
-
-  makeGroebnerBasis(input);
-  mgb::computeGroebnerBasis(input, checked);
-
-  std::ostringstream correctStr;
-  mgb::IdealStreamLog<> correct(correctStr, 101, 3);
-  mgb::IdealStreamChecker<decltype(correct)> correctChecked(correct);
-  makeGroebnerBasis(correctChecked);
-
-  EXPECT_EQ(correctStr.str(), computedStr.str())
-    << "\nDisplayed expected:\n" << correctStr.str()
-    << "\nDisplayed computed:\n" << computedStr.str();
-}
-
-TEST(MathicGBLib, Cyclic5) {
-  for (int i = 0; i < 2; ++i) {
-    mgb::GroebnerConfiguration configuration(101, 5);
-    const auto reducer = i == 0 ?
-      mgb::GroebnerConfiguration::ClassicReducer :
-      mgb::GroebnerConfiguration::MatrixReducer;
-    configuration.setReducer(reducer);
-    mgb::GroebnerInputIdealStream input(configuration);
-    makeCyclic5Basis(input);
-
-    mgb::NullIdealStream computed(input.modulus(), input.varCount());
-
-    mgb::computeGroebnerBasis(input, computed);
-  }
-}
-
-namespace {
-  class TestCallback : public mgb::GroebnerConfiguration::Callback {
-  public:
-    TestCallback(int count, Action action): mCount(count), mAction(action) {}
-
-    virtual Action call() {
-      --mCount;
-      return mCount == 0 ? mAction : ContinueAction;
-    }
-
-  private:
-    int mCount;
-    const Action mAction;
-  };
-}
-
-TEST(MathicGBLib, EarlyExit) {
-  typedef mgb::GroebnerConfiguration::Callback::Action Action;
-  auto check = [](bool useClassic, int count, Action action) {
-    mgb::GroebnerConfiguration configuration(101, 5);
-    const auto reducer = useClassic ?
-      mgb::GroebnerConfiguration::ClassicReducer :
-      mgb::GroebnerConfiguration::MatrixReducer;
-    configuration.setReducer(reducer);
-    TestCallback callback(count, action);
-    configuration.setCallback(&callback);
-    mgb::GroebnerInputIdealStream input(configuration);
-    makeCyclic5Basis(input);
-
-    std::ostringstream strOut;
-    mgb::IdealStreamLog<> out(strOut, 101, 5);
-    mgb::computeGroebnerBasis(input, out);
-    return strOut.str().size();
-  };
-
-  for (int useClassic = 0; useClassic < 2; ++useClassic) {
-    size_t none = check(useClassic, 5, Action::StopWithNoOutputAction);
-    size_t minSize = check(useClassic, 1, Action::StopWithPartialOutputAction);
-    size_t midSize = check(useClassic, 4, Action::StopWithPartialOutputAction);
-    size_t maxSize = check(useClassic, 1, Action::ContinueAction);
-    ASSERT_LT(none, 35); // the stream writes a header even for no output
-    ASSERT_LT(none, minSize);
-    ASSERT_LT(minSize, midSize);
-    ASSERT_LT(midSize, maxSize);
-  }
-}
-
-TEST(MathicGBLib, SimpleEliminationGB) {
-  std::vector<mgb::GroebnerConfiguration::Exponent> gradings = {1,0,0,0,  1,1,1,1};
-  for (int i = 0; i < 2; ++i) {
-    mgb::GroebnerConfiguration configuration(101, 4);
-    const auto reducer = i == 0 ?
-      mgb::GroebnerConfiguration::ClassicReducer :
-      mgb::GroebnerConfiguration::MatrixReducer;
-    configuration.setReducer(reducer);
-    configuration.setMonomialOrder(
-      mgb::GroebnerConfiguration::BaseOrder::ReverseLexicographicBaseOrder, 
-      gradings
-    );
-
-    mgb::GroebnerInputIdealStream input(configuration);
-    std::ostringstream computedStr;
-    mgb::IdealStreamLog<> computed(computedStr, 101, 4);
-    mgb::IdealStreamChecker<decltype(computed)> checked(computed);
-
-    makeSimpleIdeal(input);
-    mgb::computeGroebnerBasis(input, checked);
-
-    std::ostringstream correctStr;
-    mgb::IdealStreamLog<> correct(correctStr, 101, 4);
-    mgb::IdealStreamChecker<decltype(correct)> correctChecked(correct);
-    makeSimpleIdealGroebnerBasis(correctChecked);
-
-    EXPECT_EQ(correctStr.str(), computedStr.str())
-      << "\nDisplayed expected:\n" << correctStr.str()
-      << "\nDisplayed computed:\n" << computedStr.str();
-#if 0
-    mgb::GroebnerInputIdealStream input(configuration);
-    makeSimpleIdeal(input);
-    mgb::NullIdealStream computed(input.modulus(), input.varCount());
-    mgb::computeGroebnerBasis(input, computed);
-#endif
-  }
-}
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+
+#include "mathicgb.h"
+#include <gtest/gtest.h>
+
+using namespace mgb;
+
+namespace {
+  template<class Stream>
+  void makeBasis(Stream& s) {
+    s.idealBegin();
+      s.appendPolynomialBegin(); // x^2 - y
+        s.appendTermBegin();
+          s.appendExponent(0,2);
+        s.appendTermDone(1);
+        s.appendTermBegin();
+          s.appendExponent(1,1);
+        s.appendTermDone(s.modulus() - 1);
+      s.appendPolynomialDone();
+      s.appendPolynomialBegin(2); // x^3-z
+        s.appendTermBegin();
+          s.appendExponent(0,3);
+        s.appendTermDone(1);
+        s.appendTermBegin();
+          s.appendExponent(2,1);
+        s.appendTermDone(s.modulus() - 1);
+      s.appendPolynomialDone();
+    s.idealDone();
+  }
+
+  template<class Stream>
+  void makeGroebnerBasis(Stream& s) {
+    s.idealBegin(3);
+      s.appendPolynomialBegin(2); // x^2 - y
+        s.appendTermBegin();
+          s.appendExponent(0, 2);
+          s.appendExponent(1, 0);
+          s.appendExponent(2, 0);
+        s.appendTermDone(1);
+        s.appendTermBegin();
+          s.appendExponent(0, 0);
+          s.appendExponent(1, 1);
+          s.appendExponent(2, 0);
+        s.appendTermDone(s.modulus() - 1);
+      s.appendPolynomialDone();
+      s.appendPolynomialBegin(2); // xy - z
+        s.appendTermBegin();
+          s.appendExponent(0, 1);
+          s.appendExponent(1, 1);
+          s.appendExponent(2, 0);
+        s.appendTermDone(1);
+        s.appendTermBegin();
+          s.appendExponent(0, 0);
+          s.appendExponent(1, 0);
+          s.appendExponent(2, 1);
+        s.appendTermDone(s.modulus() - 1);
+      s.appendPolynomialDone();
+      s.appendPolynomialBegin(2); // y^2 - xy
+        s.appendTermBegin();
+          s.appendExponent(0, 0);
+          s.appendExponent(1, 2);
+          s.appendExponent(2, 0);
+        s.appendTermDone(1);
+        s.appendTermBegin();
+          s.appendExponent(0, 1);
+          s.appendExponent(1, 0);
+          s.appendExponent(2, 1);
+        s.appendTermDone(s.modulus() - 1);
+      s.appendPolynomialDone();
+    s.idealDone();
+  }
+
+  template<class Stream>
+  void makeCyclic5Basis(Stream& s) {
+    s.idealBegin(5); // polyCount
+    s.appendPolynomialBegin(5);
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(1, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(2, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(3, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendPolynomialDone();
+    s.appendPolynomialBegin(5);
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(3, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendPolynomialDone();
+    s.appendPolynomialBegin(5);
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendPolynomialDone();
+    s.appendPolynomialBegin(5);
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendPolynomialDone();
+    s.appendPolynomialBegin(2);
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendExponent(4, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendTermDone(100); // coefficient
+    s.appendPolynomialDone();
+    s.idealDone();
+  }
+
+  template<class Stream>
+  void makeSimpleIdeal(Stream& s) { // variables a,b,c,d.  a2-bc, ab-cd.
+    s.idealBegin();
+      s.appendPolynomialBegin(); // a^2-b*c
+        s.appendTermBegin();
+          s.appendExponent(0,2);
+        s.appendTermDone(1);
+        s.appendTermBegin();
+          s.appendExponent(1,1);
+          s.appendExponent(2,1);
+        s.appendTermDone(s.modulus() - 1);
+      s.appendPolynomialDone();
+      s.appendPolynomialBegin(2); // a*b-c*d
+        s.appendTermBegin();
+          s.appendExponent(0,1);
+          s.appendExponent(1,1);
+        s.appendTermDone(1);
+        s.appendTermBegin();
+          s.appendExponent(2,1);
+          s.appendExponent(3,1);
+        s.appendTermDone(s.modulus() - 1);
+      s.appendPolynomialDone();
+    s.idealDone();
+  }
+
+  template<class Stream>
+  void makeSimpleIdealGroebnerBasis(Stream& s) { // variables a,b,c,d.  a2-bc, ab-cd.
+    // Groebner basis is {a^2-b*c,a*b-c*d,a*c*d-b^2*c,b^3*c-c^2*d^2}
+    // (order: eliminate 1 variable: [1 0 0 0; 1 1 1 1]).
+    s.idealBegin(4); // polyCount
+    s.appendPolynomialBegin(2);
+    s.appendTermBegin();
+    s.appendExponent(0, 2); // index, exponent
+    s.appendExponent(1, 0); // index, exponent
+    s.appendExponent(2, 0); // index, exponent
+    s.appendExponent(3, 0); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 0); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 0); // index, exponent
+    s.appendTermDone(100); // coefficient
+    s.appendPolynomialDone();
+    s.appendPolynomialBegin(2);
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 1); // index, exponent
+    s.appendExponent(2, 0); // index, exponent
+    s.appendExponent(3, 0); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 0); // index, exponent
+    s.appendExponent(1, 0); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendTermDone(100); // coefficient
+    s.appendPolynomialDone();
+    s.appendPolynomialBegin(2);
+    s.appendTermBegin();
+    s.appendExponent(0, 1); // index, exponent
+    s.appendExponent(1, 0); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 1); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 0); // index, exponent
+    s.appendExponent(1, 2); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 0); // index, exponent
+    s.appendTermDone(100); // coefficient
+    s.appendPolynomialDone();
+    s.appendPolynomialBegin(2);
+    s.appendTermBegin();
+    s.appendExponent(0, 0); // index, exponent
+    s.appendExponent(1, 3); // index, exponent
+    s.appendExponent(2, 1); // index, exponent
+    s.appendExponent(3, 0); // index, exponent
+    s.appendTermDone(1); // coefficient
+    s.appendTermBegin();
+    s.appendExponent(0, 0); // index, exponent
+    s.appendExponent(1, 0); // index, exponent
+    s.appendExponent(2, 2); // index, exponent
+    s.appendExponent(3, 2); // index, exponent
+    s.appendTermDone(100); // coefficient
+    s.appendPolynomialDone();
+    s.idealDone();
+  }
+}
+
+TEST(MathicGBLib, NullIdealStream) {
+  {
+    mgb::NullIdealStream stream(2, 3);
+    ASSERT_EQ(2, stream.modulus());
+    ASSERT_EQ(3, stream.varCount());
+    makeBasis(stream);
+  }
+
+  {
+    mgb::NullIdealStream stream(101, 0);
+    ASSERT_EQ(101, stream.modulus());
+    ASSERT_EQ(0, stream.varCount());
+  }
+}
+
+TEST(MathicGBLib, IdealStreamLog) {
+  {
+    const char* const idealStr = 
+      "s.idealBegin();\n"
+      "s.appendPolynomialBegin();\n"
+      "s.appendTermBegin();\n"
+      "s.appendExponent(0, 2); // index, exponent\n"
+      "s.appendTermDone(1); // coefficient\n"
+      "s.appendTermBegin();\n"
+      "s.appendExponent(1, 1); // index, exponent\n"
+      "s.appendTermDone(6); // coefficient\n"
+      "s.appendPolynomialDone();\n"
+      "s.appendPolynomialBegin(2);\n"
+      "s.appendTermBegin();\n"
+      "s.appendExponent(0, 3); // index, exponent\n"
+      "s.appendTermDone(1); // coefficient\n"
+      "s.appendTermBegin();\n"
+      "s.appendExponent(2, 1); // index, exponent\n"
+      "s.appendTermDone(6); // coefficient\n"
+      "s.appendPolynomialDone();\n"
+      "s.idealDone();\n";
+
+    std::ostringstream out1;
+    mgb::IdealStreamLog<> stream1(out1, 7, 3);
+
+    mgb::IdealStreamChecker<decltype(stream1)> checker(stream1);
+
+    std::ostringstream out2;
+    mgb::IdealStreamLog<decltype(checker)> stream2(out2, checker);
+
+    std::ostringstream out3;
+    mgb::IdealStreamLog<decltype(stream2)> stream3(out3, stream2);
+
+    ASSERT_EQ(7, stream1.modulus());
+    ASSERT_EQ(3, stream1.varCount());
+    ASSERT_EQ(7, checker.modulus());
+    ASSERT_EQ(3, checker.varCount());
+    ASSERT_EQ(7, stream2.modulus());
+    ASSERT_EQ(3, stream2.varCount());
+    ASSERT_EQ(7, stream3.modulus());
+    ASSERT_EQ(3, stream3.varCount());
+
+    makeBasis(stream3);
+    const auto str1 = std::string(
+      "IdealStreamLog s(stream, 7, 3);\n"
+    ) + idealStr;
+    ASSERT_EQ(str1, out1.str())
+      << "Displayed expected:\n" << out1.str()
+      << "Displayed actual:\n" << str1 << std::endl;
+
+    const auto str2 = std::string(
+      "IdealStreamLog s(stream, log); // modulus=7, varCount=3\n"
+    ) + idealStr;
+    ASSERT_EQ(str2, out2.str()) << "Displayed expected:\n" << out2.str();
+    ASSERT_EQ(str2, out3.str()) << "Displayed expected:\n" << out3.str();
+  }
+
+  // The ideal <> in no variables
+  {
+    std::ostringstream out;
+    mgb::IdealStreamLog<> stream(out, 101, 0);
+    ASSERT_EQ(101, stream.modulus());
+    ASSERT_EQ(0, stream.varCount());
+    stream.idealBegin(0);
+    stream.idealDone();
+  }
+
+  // The ideal <1, 0> in no variables
+  {
+    std::ostringstream out;
+    mgb::IdealStreamLog<> stream(out, 101, 0);
+    ASSERT_EQ(101, stream.modulus());
+    ASSERT_EQ(0, stream.varCount());
+    stream.idealBegin(2);
+      stream.appendPolynomialBegin(0); // 1
+        stream.appendTermBegin();
+        stream.appendTermDone(1);
+      stream.appendPolynomialDone();
+      stream.appendPolynomialBegin(0); // 0
+      stream.appendPolynomialDone();
+    stream.idealDone();
+  }
+}
+
+TEST(MathicGBLib, ZeroIdealGB) {
+  mgb::GroebnerConfiguration configuration(2, 0);
+  mgb::GroebnerInputIdealStream input(configuration);
+  std::ostringstream out;
+  mgb::IdealStreamLog<> logStream(out, 2, 0);
+
+  input.idealBegin(0);
+  input.idealDone();
+  mgb::computeGroebnerBasis(input, logStream);
+
+  const auto msg =
+    "IdealStreamLog s(stream, 2, 0);\n"
+    "s.idealBegin(0); // polyCount\n"
+    "s.idealDone();\n";
+  EXPECT_EQ(msg, out.str());
+}
+
+TEST(MathicGBLib, OneIdealGB) {
+  mgb::GroebnerConfiguration configuration(2, 0);
+  mgb::GroebnerInputIdealStream input(configuration);
+  std::ostringstream out;
+  mgb::IdealStreamLog<> logStream(out, 2, 0);
+
+  input.idealBegin(1);
+  input.appendPolynomialBegin(1);
+  input.appendTermBegin();
+  input.appendTermDone(1);
+  input.appendPolynomialDone();
+  input.idealDone();
+  mgb::computeGroebnerBasis(input, logStream);
+
+  const auto msg =
+     "IdealStreamLog s(stream, 2, 0);\n"
+     "s.idealBegin(1); // polyCount\n"
+     "s.appendPolynomialBegin(1);\n"
+     "s.appendTermBegin();\n"
+     "s.appendTermDone(1); // coefficient\n"
+     "s.appendPolynomialDone();\n"
+     "s.idealDone();\n";
+  EXPECT_EQ(msg, out.str());
+}
+
+TEST(MathicGBLib, EasyGB) {
+  mgb::GroebnerConfiguration configuration(101, 3);
+  mgb::GroebnerInputIdealStream input(configuration);
+  std::ostringstream computedStr;
+  mgb::IdealStreamLog<> computed(computedStr, 101, 3);
+  mgb::IdealStreamChecker<decltype(computed)> checked(computed);
+
+  makeBasis(input);
+  mgb::computeGroebnerBasis(input, checked);
+
+  std::ostringstream correctStr;
+  mgb::IdealStreamLog<> correct(correctStr, 101, 3);
+  mgb::IdealStreamChecker<decltype(correct)> correctChecked(correct);
+  makeGroebnerBasis(correctChecked);
+
+  EXPECT_EQ(correctStr.str(), computedStr.str())
+    << "\nDisplayed expected:\n" << correctStr.str()
+    << "\nDisplayed computed:\n" << computedStr.str();
+}
+
+TEST(MathicGBLib, EasyReGB) {
+  mgb::GroebnerConfiguration configuration(101, 3);
+  mgb::GroebnerInputIdealStream input(configuration);
+  std::ostringstream computedStr;
+  mgb::IdealStreamLog<> computed(computedStr, 101, 3);
+  mgb::IdealStreamChecker<decltype(computed)> checked(computed);
+
+  makeGroebnerBasis(input);
+  mgb::computeGroebnerBasis(input, checked);
+
+  std::ostringstream correctStr;
+  mgb::IdealStreamLog<> correct(correctStr, 101, 3);
+  mgb::IdealStreamChecker<decltype(correct)> correctChecked(correct);
+  makeGroebnerBasis(correctChecked);
+
+  EXPECT_EQ(correctStr.str(), computedStr.str())
+    << "\nDisplayed expected:\n" << correctStr.str()
+    << "\nDisplayed computed:\n" << computedStr.str();
+}
+
+TEST(MathicGBLib, Cyclic5) {
+  for (int i = 0; i < 2; ++i) {
+    mgb::GroebnerConfiguration configuration(101, 5);
+    const auto reducer = i == 0 ?
+      mgb::GroebnerConfiguration::ClassicReducer :
+      mgb::GroebnerConfiguration::MatrixReducer;
+    configuration.setReducer(reducer);
+    mgb::GroebnerInputIdealStream input(configuration);
+    makeCyclic5Basis(input);
+
+    mgb::NullIdealStream computed(input.modulus(), input.varCount());
+
+    mgb::computeGroebnerBasis(input, computed);
+  }
+}
+
+namespace {
+  class TestCallback : public mgb::GroebnerConfiguration::Callback {
+  public:
+    TestCallback(int count, Action action): mCount(count), mAction(action) {}
+
+    virtual Action call() {
+      --mCount;
+      return mCount == 0 ? mAction : ContinueAction;
+    }
+
+  private:
+    int mCount;
+    const Action mAction;
+  };
+}
+
+TEST(MathicGBLib, EarlyExit) {
+  typedef mgb::GroebnerConfiguration::Callback::Action Action;
+  auto check = [](bool useClassic, int count, Action action) {
+    mgb::GroebnerConfiguration configuration(101, 5);
+    const auto reducer = useClassic ?
+      mgb::GroebnerConfiguration::ClassicReducer :
+      mgb::GroebnerConfiguration::MatrixReducer;
+    configuration.setReducer(reducer);
+    TestCallback callback(count, action);
+    configuration.setCallback(&callback);
+    mgb::GroebnerInputIdealStream input(configuration);
+    makeCyclic5Basis(input);
+
+    std::ostringstream strOut;
+    mgb::IdealStreamLog<> out(strOut, 101, 5);
+    mgb::computeGroebnerBasis(input, out);
+    return strOut.str().size();
+  };
+
+  for (int useClassic = 0; useClassic < 2; ++useClassic) {
+    size_t none = check(useClassic, 5, Action::StopWithNoOutputAction);
+    size_t minSize = check(useClassic, 1, Action::StopWithPartialOutputAction);
+    size_t midSize = check(useClassic, 4, Action::StopWithPartialOutputAction);
+    size_t maxSize = check(useClassic, 1, Action::ContinueAction);
+    ASSERT_LT(none, 35); // the stream writes a header even for no output
+    ASSERT_LT(none, minSize);
+    ASSERT_LT(minSize, midSize);
+    ASSERT_LT(midSize, maxSize);
+  }
+}
+
+TEST(MathicGBLib, SimpleEliminationGB) {
+  std::vector<mgb::GroebnerConfiguration::Exponent> gradings = {1,0,0,0,  1,1,1,1};
+  for (int i = 0; i < 2; ++i) {
+    mgb::GroebnerConfiguration configuration(101, 4);
+    const auto reducer = i == 0 ?
+      mgb::GroebnerConfiguration::ClassicReducer :
+      mgb::GroebnerConfiguration::MatrixReducer;
+    configuration.setReducer(reducer);
+    configuration.setMonomialOrder(
+      mgb::GroebnerConfiguration::BaseOrder::ReverseLexicographicBaseOrder, 
+      gradings
+    );
+
+    mgb::GroebnerInputIdealStream input(configuration);
+    std::ostringstream computedStr;
+    mgb::IdealStreamLog<> computed(computedStr, 101, 4);
+    mgb::IdealStreamChecker<decltype(computed)> checked(computed);
+
+    makeSimpleIdeal(input);
+    mgb::computeGroebnerBasis(input, checked);
+
+    std::ostringstream correctStr;
+    mgb::IdealStreamLog<> correct(correctStr, 101, 4);
+    mgb::IdealStreamChecker<decltype(correct)> correctChecked(correct);
+    makeSimpleIdealGroebnerBasis(correctChecked);
+
+    EXPECT_EQ(correctStr.str(), computedStr.str())
+      << "\nDisplayed expected:\n" << correctStr.str()
+      << "\nDisplayed computed:\n" << computedStr.str();
+#if 0
+    mgb::GroebnerInputIdealStream input(configuration);
+    makeSimpleIdeal(input);
+    mgb::NullIdealStream computed(input.modulus(), input.varCount());
+    mgb::computeGroebnerBasis(input, computed);
+#endif
+  }
+}
+
diff --git a/src/test/monoidPict.in b/src/test/monoidPict.in
index 200ee7f..5da0f2a 100755
--- a/src/test/monoidPict.in
+++ b/src/test/monoidPict.in
@@ -1,29 +1,29 @@
-# See pict.in for what pict files do.
-# This file is for getting a good set of test instantiations of MonoMonoid.
-# See the test file MonoMonoid.cpp.
-#
-# To generate a set of test configurations, do
-#
-#   pict monoidPict.in /e:monoidPict.seed > monoidPict.out
-#
-# Then reformat the output and put it into MonoMonoid.cpp as the set
-# of PolyRing configurations to use.
-
-##############################################################
-# This is the PICT model specifying all parameters and their values
-#
-Exponent: int8, int16, int32
-HasComponent: 0,1
-StoreHash: 0,1
-StoreOrder: 0,1
-
-##############################################################
-# PICT submodels go here.
-#
-
-# we are not currently using PICT submodels
-
-##############################################################
-# This is the set of PICT constraints that rule out some combinations
-# of parameter values.
-#
+# See pict.in for what pict files do.
+# This file is for getting a good set of test instantiations of MonoMonoid.
+# See the test file MonoMonoid.cpp.
+#
+# To generate a set of test configurations, do
+#
+#   pict monoidPict.in /e:monoidPict.seed > monoidPict.out
+#
+# Then reformat the output and put it into MonoMonoid.cpp as the set
+# of PolyRing configurations to use.
+
+##############################################################
+# This is the PICT model specifying all parameters and their values
+#
+Exponent: int8, int16, int32
+HasComponent: 0,1
+StoreHash: 0,1
+StoreOrder: 0,1
+
+##############################################################
+# PICT submodels go here.
+#
+
+# we are not currently using PICT submodels
+
+##############################################################
+# This is the set of PICT constraints that rule out some combinations
+# of parameter values.
+#
diff --git a/src/test/monoidPict.seed b/src/test/monoidPict.seed
index 44aa83c..faf9bed 100755
--- a/src/test/monoidPict.seed
+++ b/src/test/monoidPict.seed
@@ -1,9 +1,9 @@
-Exponent	HasComponent	StoreHash	StoreOrder
-int32	1	1	1
-int32	0	1	1
-int32	0	0	1
-int32	0	0	0
-int16	1	1	1
-int16	0	1	1
-int16	0	0	1
-int16	0	0	0
+Exponent	HasComponent	StoreHash	StoreOrder
+int32	1	1	1
+int32	0	1	1
+int32	0	0	1
+int32	0	0	0
+int16	1	1	1
+int16	0	1	1
+int16	0	0	1
+int16	0	0	0
diff --git a/src/test/pict.in b/src/test/pict.in
index 0557a0b..1d8cdb0 100755
--- a/src/test/pict.in
+++ b/src/test/pict.in
@@ -1,58 +1,58 @@
-# The purpose of this file is to generate a set of test configurations
-# where every pair of parameter values is present at least once. See
-# the Wikipedia page on all pairs testing:
-#
-#  http://en.wikipedia.org/wiki/All-pairs_testing
-#
-# This file is an input file for the Microsoft testing tool PICT.
-# The tool is available at
-#
-#   http://download.microsoft.com/download/f/5/5/f55484df-8494-48fa-8dbd-8c6f76cc014b/pict33.msi 
-#
-# You will need to run this program on Windows. It is a closed source
-# utility. There are open sources alternatives but they are not as good.
-#
-# To update the test in gb-test.cpp, do
-#
-#   pict pict.in > pict.out
-#
-# Then place the entire contents of pict.out (including newlines) into
-# the string allPairsTest in gb-test.cpp.
-
-##############################################################
-# This is the PICT model specifying all parameters and their values
-#
-spairQueue: 0,1,2,3
-reducerType: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
-divLookup: 1, 2, 3, 4
-monTable: 0, 1, 2
-buchberger: 0, 1
-postponeKoszul: 0, 1
-useBaseDivisors: 0, 1
-autoTailReduce: 0,1
-autoTopReduce: 0,1
-preferSparseReducers: 0,1
-useSingularCriterionEarly: 0, 1
-sPairGroupSize: 0, 1, 2, 10, 100
-threadCount: 1, 2, 8
-
-##############################################################
-# PICT submodels go here.
-#
-
-# we are not currently using PICT submodels
-
-##############################################################
-# This is the set of PICT constraints that rule out some combinations
-# of parameter values.
-#
-IF [buchberger] = 0 THEN
-  [autoTopReduce] = 0 AND
-  [autoTailReduce] = 0 AND
-  [reducerType] <> 25 AND
-  [reducerType] <> 26;
-
-IF [buchberger] = 1 THEN
-  [postponeKoszul] = 0 AND
-  [useBaseDivisors] = 0 AND
-  [usesingularCriterionEarly] = 0;
+# The purpose of this file is to generate a set of test configurations
+# where every pair of parameter values is present at least once. See
+# the Wikipedia page on all pairs testing:
+#
+#  http://en.wikipedia.org/wiki/All-pairs_testing
+#
+# This file is an input file for the Microsoft testing tool PICT.
+# The tool is available at
+#
+#   http://download.microsoft.com/download/f/5/5/f55484df-8494-48fa-8dbd-8c6f76cc014b/pict33.msi 
+#
+# You will need to run this program on Windows. It is a closed source
+# utility. There are open sources alternatives but they are not as good.
+#
+# To update the test in gb-test.cpp, do
+#
+#   pict pict.in > pict.out
+#
+# Then place the entire contents of pict.out (including newlines) into
+# the string allPairsTest in gb-test.cpp.
+
+##############################################################
+# This is the PICT model specifying all parameters and their values
+#
+spairQueue: 0,1,2,3
+reducerType: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
+divLookup: 1, 2, 3, 4
+monTable: 0, 1, 2
+buchberger: 0, 1
+postponeKoszul: 0, 1
+useBaseDivisors: 0, 1
+autoTailReduce: 0,1
+autoTopReduce: 0,1
+preferSparseReducers: 0,1
+useSingularCriterionEarly: 0, 1
+sPairGroupSize: 0, 1, 2, 10, 100
+threadCount: 1, 2, 8
+
+##############################################################
+# PICT submodels go here.
+#
+
+# we are not currently using PICT submodels
+
+##############################################################
+# This is the set of PICT constraints that rule out some combinations
+# of parameter values.
+#
+IF [buchberger] = 0 THEN
+  [autoTopReduce] = 0 AND
+  [autoTailReduce] = 0 AND
+  [reducerType] <> 25 AND
+  [reducerType] <> 26;
+
+IF [buchberger] = 1 THEN
+  [postponeKoszul] = 0 AND
+  [useBaseDivisors] = 0 AND
+  [usesingularCriterionEarly] = 0;
diff --git a/src/test/poly-test.cpp b/src/test/poly-test.cpp
index 09a7f61..d00fc09 100755
--- a/src/test/poly-test.cpp
+++ b/src/test/poly-test.cpp
@@ -1,27 +1,27 @@
-// Copyright 2011 Michael E. Stillman
-
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
 #include "mathicgb/stdinc.h"
-#include <cstdio>
-#include <string>
-#include <iostream>
-#include <sstream>
-
 #include "mathicgb/Poly.hpp"
+
 #include "mathicgb/Basis.hpp"
 #include "mathicgb/MonTableNaive.hpp"
 #include "mathicgb/MonTableKDTree.hpp"
 #include "mathicgb/MonTableDivList.hpp"
 #include "mathicgb/MTArray.hpp"
 #include "mathicgb/io-util.hpp"
-
 #include "mathicgb/MonomialHashTable.hpp"
 #include "mathicgb/PolyHashTable.hpp"
 #include "mathicgb/PolyHeap.hpp"
 #include "mathicgb/PolyGeoBucket.hpp"
 #include "mathicgb/SigPolyBasis.hpp"
 #include "mathicgb/SignatureGB.hpp"
-
 #include <gtest/gtest.h>
+#include <cstdio>
+#include <string>
+#include <iostream>
+#include <sstream>
+
+using namespace mgb;
 
 std::string ideal1 =
 "32003 4 1 1 1 1 1 \
@@ -829,8 +829,3 @@ TEST(MonomialHashTable,test1) {
   H.getStats(stats);
   //H.dump(1);
 }
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/test/testMain.cpp b/src/test/testMain.cpp
index 4d820af..6fe8117 100755
--- a/src/test/testMain.cpp
+++ b/src/test/testMain.cpp
@@ -1,5 +1,11 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#include "mathicgb/stdinc.h"
+
 #include <gtest/gtest.h>
 
+using namespace mgb;
+
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathicgb.git



More information about the debian-science-commits mailing list