[cg3] 01/02: Imported Upstream version 0.9.9~r10439

Tino Didriksen tinodidriksen-guest at moszumanska.debian.org
Sun Feb 8 23:40:40 UTC 2015


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

tinodidriksen-guest pushed a commit to branch master
in repository cg3.

commit 33f81a130a3a628416351c1a4ceb5ff08a64f9ee
Author: Tino Didriksen <mail at tinodidriksen.com>
Date:   Sun Feb 8 23:40:20 2015 +0000

    Imported Upstream version 0.9.9~r10439
---
 CMake/FindBoost.cmake                              | 938 ---------------------
 CMakeLists.txt                                     |  19 +-
 ChangeLog                                          | 197 +++--
 TODO                                               |   1 +
 compile-profile.sh                                 |   4 +-
 emacs/cg.el                                        | 100 ++-
 manual/installation.xml                            |  24 +-
 scripts/profile-revisions.php                      |  12 +-
 src/ApertiumApplicator.cpp                         |   6 +-
 src/ApertiumApplicator.hpp                         |   2 +-
 src/BinaryGrammar.cpp                              |   6 +-
 src/BinaryGrammar.hpp                              |   7 +-
 src/BinaryGrammar_read.cpp                         |  51 +-
 ...ammar_read.cpp => BinaryGrammar_read_10043.cpp} |  47 +-
 src/BinaryGrammar_write.cpp                        |  59 +-
 src/CMakeLists.txt                                 |   9 +-
 src/Cohort.cpp                                     |   2 +-
 src/Cohort.hpp                                     |   2 +-
 src/CohortIterator.cpp                             |   2 +-
 src/CohortIterator.hpp                             |   2 +-
 src/ContextualTest.cpp                             |   4 +-
 src/ContextualTest.hpp                             |   4 +-
 src/FSTApplicator.cpp                              |   8 +-
 src/FSTApplicator.hpp                              |   2 +-
 src/FormatConverter.cpp                            |   2 +-
 src/FormatConverter.hpp                            |   2 +-
 src/Grammar.cpp                                    | 245 ++++--
 src/Grammar.hpp                                    |  12 +-
 src/GrammarApplicator.cpp                          |  15 +-
 src/GrammarApplicator.hpp                          |   6 +-
 src/GrammarApplicator_matchSet.cpp                 |  50 +-
 src/GrammarApplicator_reflow.cpp                   |  17 +-
 src/GrammarApplicator_runContextualTest.cpp        |   2 +-
 src/GrammarApplicator_runGrammar.cpp               |   8 +-
 src/GrammarApplicator_runRules.cpp                 |  55 +-
 src/GrammarWriter.cpp                              |  41 +-
 src/GrammarWriter.hpp                              |   2 +-
 src/IGrammarParser.hpp                             |   3 +-
 src/NicelineApplicator.cpp                         |   8 +-
 src/NicelineApplicator.hpp                         |   2 +-
 src/PlaintextApplicator.cpp                        |   8 +-
 src/PlaintextApplicator.hpp                        |   2 +-
 src/Reading.cpp                                    |   2 +-
 src/Reading.hpp                                    |   2 +-
 src/Rule.cpp                                       |   6 +-
 src/Rule.hpp                                       |   2 +-
 src/Set.cpp                                        |   2 +-
 src/Set.hpp                                        |   2 +-
 src/SingleWindow.cpp                               |   2 +-
 src/SingleWindow.hpp                               |   2 +-
 src/Strings.cpp                                    |   2 +-
 src/Strings.hpp                                    |   2 +-
 src/Tag.cpp                                        |   2 +-
 src/Tag.hpp                                        |   2 +-
 src/TagTrie.hpp                                    |   2 +-
 src/TextualParser.cpp                              |  12 +-
 src/TextualParser.hpp                              |   2 +-
 src/Window.cpp                                     |   2 +-
 src/Window.hpp                                     |   2 +-
 src/bloomish.hpp                                   |   2 +-
 src/cg3.h                                          |   2 +-
 src/cg_comp.cpp                                    |   4 +-
 src/cg_conv.cpp                                    |   3 +-
 src/cg_proc.cpp                                    |   2 +-
 src/flat_unordered_map.hpp                         |  16 +-
 src/flat_unordered_set.hpp                         |  20 +-
 src/inlines.hpp                                    |   8 +-
 src/interval_vector.hpp                            |   9 +-
 src/istream.hpp                                    |   2 +-
 src/libcg3.cpp                                     |   2 +-
 src/macros.hpp                                     |   2 +-
 src/main.cpp                                       |   8 +-
 src/options.hpp                                    |   2 +-
 src/options_conv.hpp                               |   2 +-
 src/sorted_vector.hpp                              |  38 +-
 src/stdafx.hpp                                     |   7 +-
 src/test_libcg3.c                                  |   2 +-
 src/uextras.cpp                                    |   2 +-
 src/uextras.hpp                                    |   2 +-
 src/version.hpp                                    |  10 +-
 test/T_AnyMinusSome/args.txt                       |   1 +
 test/T_AnyMinusSome/grammar.cg3b.10043             | Bin 0 -> 558 bytes
 test/T_AnyMinusSome/run.pl                         |  32 -
 test/T_Barrier/grammar.cg3b.10043                  | Bin 0 -> 738 bytes
 test/T_Barrier/run.pl                              |  32 -
 test/T_BasicAppend/grammar.cg3b.10043              | Bin 0 -> 2071 bytes
 test/T_BasicAppend/run.pl                          |  32 -
 test/T_BasicContextTest/grammar.cg3b.10043         | Bin 0 -> 1548 bytes
 test/T_BasicContextTest/run.pl                     |  32 -
 test/T_BasicDelimit/args.txt                       |   1 +
 test/T_BasicDelimit/expected.txt                   |  10 +-
 test/T_BasicDelimit/grammar.cg3b.10043             | Bin 0 -> 500 bytes
 test/T_BasicDelimit/run.pl                         |  32 -
 test/T_BasicDependency/args.txt                    |   1 +
 test/T_BasicDependency/grammar.cg3b.10043          | Bin 0 -> 8729 bytes
 test/T_BasicDependency/run.pl                      |  32 -
 test/T_BasicIff/grammar.cg3b.10043                 | Bin 0 -> 596 bytes
 test/T_BasicIff/run.pl                             |  32 -
 test/T_BasicSelect/args.txt                        |   1 +
 test/T_BasicSelect/grammar.cg3b.10043              | Bin 0 -> 837 bytes
 test/T_BasicSelect/run.pl                          |  32 -
 test/T_BasicSubstitute/args.txt                    |   1 +
 test/T_BasicSubstitute/grammar.cg3b.10043          | Bin 0 -> 2155 bytes
 test/T_BasicSubstitute/run.pl                      |  32 -
 test/T_CG2Compat/args.txt                          |   1 +
 test/T_CG2Compat/grammar.cg3b.10043                | Bin 0 -> 1106 bytes
 test/T_CG2Compat/run.pl                            |  32 -
 test/T_CarefulBarrier/grammar.cg3b.10043           | Bin 0 -> 704 bytes
 test/T_CarefulBarrier/run.pl                       |  32 -
 test/T_DelayAndDelete/grammar.cg3b.10043           | Bin 0 -> 3055 bytes
 test/T_DelayAndDelete/run.pl                       |  32 -
 test/T_Dependency_Loops/args.txt                   |   1 +
 test/T_Dependency_Loops/grammar.cg3b.10043         | Bin 0 -> 2071 bytes
 test/T_Dependency_Loops/run.pl                     |  32 -
 test/T_Dependency_OutOfRange/expected.txt          |   2 +-
 test/T_Dependency_OutOfRange/grammar.cg3           |   8 +-
 test/T_Dependency_OutOfRange/grammar.cg3b.10043    | Bin 0 -> 1643 bytes
 test/T_Dependency_OutOfRange/run.pl                |  32 -
 test/T_DontMatchEmptySet/grammar.cg3b.10043        | Bin 0 -> 597 bytes
 test/T_DontMatchEmptySet/run.pl                    |  32 -
 test/T_EndlessSelect/grammar.cg3b.10043            | Bin 0 -> 496 bytes
 test/T_EndlessSelect/run.pl                        |  32 -
 test/T_External/grammar.cg3b.10043                 | Bin 0 -> 833 bytes
 test/T_Include/grammar.cg3b.10043                  | Bin 0 -> 837 bytes
 test/T_Include/run.pl                              |  32 -
 test/T_InputCommands/grammar.cg3b.10043            | Bin 0 -> 594 bytes
 test/T_InputCommands/run.pl                        |  32 -
 test/T_InputMarkup/grammar.cg3b.10043              | Bin 0 -> 597 bytes
 test/T_InputMarkup/run.pl                          |  32 -
 test/T_JumpExecute/args.txt                        |   1 +
 test/T_JumpExecute/grammar.cg3b.10043              | Bin 0 -> 1163 bytes
 test/T_JumpExecute/run.pl                          |  32 -
 test/T_MapAdd_Different/args.txt                   |   1 +
 test/T_MapAdd_Different/expected.txt               |   2 +-
 test/T_MapAdd_Different/grammar.cg3                |   4 +-
 test/T_MapAdd_Different/grammar.cg3b.10043         | Bin 0 -> 907 bytes
 test/T_MapAdd_Different/run.pl                     |  32 -
 test/T_MapThenRemove/grammar.cg3b.10043            | Bin 0 -> 841 bytes
 test/T_MapThenRemove/run.pl                        |  32 -
 test/T_MapThenSelect/grammar.cg3b.10043            | Bin 0 -> 1000 bytes
 test/T_MapThenSelect/run.pl                        |  32 -
 test/T_MappingPrefix/args.txt                      |   1 +
 test/T_MappingPrefix/grammar.cg3b.10043            | Bin 0 -> 1467 bytes
 test/T_MappingPrefix/run.pl                        |  32 -
 test/T_Movement/grammar.cg3b.10043                 | Bin 0 -> 1574 bytes
 test/T_Movement/run.pl                             |  32 -
 test/T_MultipleSections/grammar.cg3b.10043         | Bin 0 -> 632 bytes
 test/T_MultipleSections/run.pl                     |  32 -
 test/T_NegatedContextTest/grammar.cg3b.10043       | Bin 0 -> 612 bytes
 test/T_NegatedContextTest/run.pl                   |  32 -
 test/T_NotContextTest/grammar.cg3b.10043           | Bin 0 -> 592 bytes
 test/T_NotContextTest/run.pl                       |  32 -
 test/T_NumericalTags/args.txt                      |   1 +
 test/T_NumericalTags/grammar.cg3b.10043            | Bin 0 -> 2503 bytes
 test/T_NumericalTags/run.pl                        |  32 -
 test/T_OmniWithBarrier/grammar.cg3b.10043          | Bin 0 -> 784 bytes
 test/T_OmniWithBarrier/run.pl                      |  32 -
 test/T_Omniscan/grammar.cg3b.10043                 | Bin 0 -> 1689 bytes
 test/T_Omniscan/run.pl                             |  32 -
 test/T_OriginPassing/args.txt                      |   1 +
 test/T_OriginPassing/grammar.cg3b.10043            | Bin 0 -> 3368 bytes
 test/T_OriginPassing/run.pl                        |  32 -
 test/T_Parentheses/args.txt                        |   1 +
 test/T_Parentheses/grammar.cg3b.10043              | Bin 0 -> 2869 bytes
 test/T_Parentheses/run.pl                          |  32 -
 test/T_RegExp/grammar.cg3b.10043                   | Bin 0 -> 3827 bytes
 test/T_RegExp/run.pl                               |  32 -
 test/T_Relations/args.txt                          |   1 +
 test/T_Relations/grammar.cg3b.10043                | Bin 0 -> 2970 bytes
 test/T_Relations/run.pl                            |  32 -
 test/T_RemCohort/args.txt                          |   1 +
 test/T_RemCohort/grammar.cg3b.10043                | Bin 0 -> 2239 bytes
 test/T_RemCohort/run.pl                            |  32 -
 test/T_RemoveSingleTag/grammar.cg3b.10043          | Bin 0 -> 591 bytes
 test/T_RemoveSingleTag/run.pl                      |  32 -
 test/T_ScanningTests/grammar.cg3b.10043            | Bin 0 -> 2289 bytes
 test/T_ScanningTests/run.pl                        |  32 -
 test/T_SectionRanges/args.txt                      |   1 +
 test/T_SectionRanges/grammar.cg3b.10043            | Bin 0 -> 1175 bytes
 test/T_SectionRanges/run.pl                        |  32 -
 test/T_Sections/args.txt                           |   1 +
 test/T_Sections/grammar.cg3b.10043                 | Bin 0 -> 715 bytes
 test/T_Sections/run.pl                             |  32 -
 test/T_SetOp_FailFast/args.txt                     |   1 +
 test/T_SetOp_FailFast/grammar.cg3b.10043           | Bin 0 -> 906 bytes
 test/T_SetOp_FailFast/run.pl                       |  32 -
 test/T_SetOps/grammar.cg3b.10043                   | Bin 0 -> 1437 bytes
 test/T_SetOps/run.pl                               |  32 -
 test/T_SetParentChild/grammar.cg3b.10043           | Bin 0 -> 1660 bytes
 test/T_SetParentChild/run.pl                       |  32 -
 test/T_SoftDelimiters/args.txt                     |   1 +
 test/T_SoftDelimiters/grammar.cg3b.10043           | Bin 0 -> 645 bytes
 test/T_SoftDelimiters/run.pl                       |  32 -
 test/T_SpaceInForms/args.txt                       |   1 +
 test/T_SpaceInForms/grammar.cg3b.10043             | Bin 0 -> 1520 bytes
 test/T_SpaceInForms/run.pl                         |  32 -
 test/T_SubReadings_Apertium/grammar.cg3b.10043     | Bin 0 -> 2027 bytes
 test/T_SubReadings_CG/args.txt                     |   1 +
 test/T_SubReadings_CG/grammar.cg3b.10043           | Bin 0 -> 2370 bytes
 test/T_SubReadings_CG/run.pl                       |  32 -
 test/T_SubstituteNil/grammar.cg3b.10043            | Bin 0 -> 543 bytes
 test/T_SubstituteNil/run.pl                        |  32 -
 test/T_Templates/grammar.cg3b.10043                | Bin 0 -> 5270 bytes
 test/T_Templates/run.pl                            |  32 -
 test/T_Trace/args.txt                              |   1 +
 test/T_Trace/grammar.cg3b.10043                    | Bin 0 -> 818 bytes
 test/T_Trace/run.pl                                |  32 -
 test/T_Unification/args.txt                        |   1 +
 test/T_Unification/grammar.cg3b.10043              | Bin 0 -> 4574 bytes
 test/T_Unification/run.pl                          |  32 -
 test/T_Variables/grammar.cg3b.10043                | Bin 0 -> 1124 bytes
 test/T_Variables/run.pl                            |  32 -
 test/runall.pl                                     |  72 +-
 vapply.sh                                          |   2 +-
 vparse.sh                                          |   2 +-
 215 files changed, 867 insertions(+), 3071 deletions(-)

diff --git a/CMake/FindBoost.cmake b/CMake/FindBoost.cmake
deleted file mode 100644
index a1c7c20..0000000
--- a/CMake/FindBoost.cmake
+++ /dev/null
@@ -1,938 +0,0 @@
-# - Try to find Boost include dirs and libraries
-# Usage of this module as follows:
-#
-# NOTE: Take note of the Boost_ADDITIONAL_VERSIONS variable below.
-# Due to Boost naming conventions and limitations in CMake this find
-# module is NOT future safe with respect to Boost version numbers,
-# and may break.
-#
-# == Using Header-Only libraries from within Boost: ==
-#
-#   find_package( Boost 1.36.0 )
-#   if(Boost_FOUND)
-#      include_directories(${Boost_INCLUDE_DIRS})
-#      add_executable(foo foo.cc)
-#   endif()
-#
-#
-# == Using actual libraries from within Boost: ==
-#
-#   set(Boost_USE_STATIC_LIBS   ON)
-#   set(Boost_USE_MULTITHREADED ON)
-#   find_package( Boost 1.36.0 COMPONENTS date_time filesystem system ... )
-#
-#   if(Boost_FOUND)
-#      include_directories(${Boost_INCLUDE_DIRS})
-#      add_executable(foo foo.cc)
-#      target_link_libraries(foo ${Boost_LIBRARIES})
-#   endif()
-#
-#
-# The components list needs to contain actual names of boost libraries only,
-# such as "date_time" for "libboost_date_time".  If you're using parts of
-# Boost that contain header files only (e.g. foreach) you do not need to
-# specify COMPONENTS.
-#
-# You should provide a minimum version number that should be used. If you provide this 
-# version number and specify the REQUIRED attribute, this module will fail if it
-# can't find the specified or a later version. If you specify a version number this is
-# automatically put into the considered list of version numbers and thus doesn't need
-# to be specified in the Boost_ADDITIONAL_VERSIONS variable (see below).
-#
-# NOTE for Visual Studio Users:
-#     Automatic linking is used on MSVC & Borland compilers by default when
-#     #including things in Boost.  It's important to note that setting
-#     Boost_USE_STATIC_LIBS to OFF is NOT enough to get you dynamic linking,
-#     should you need this feature.  Automatic linking typically uses static
-#     libraries with a few exceptions (Boost.Python is one).
-#
-#     Please see the section below near Boost_LIB_DIAGNOSTIC_DEFINITIONS for
-#     more details.  Adding a TARGET_LINK_LIBRARIES() as shown in the example
-#     above appears to cause VS to link dynamically if Boost_USE_STATIC_LIBS
-#     gets set to OFF.  It is suggested you avoid automatic linking since it
-#     will make your application less portable.
-#
-# =========== The mess that is Boost_ADDITIONAL_VERSIONS (sorry?) ============
-#
-# OK, so the Boost_ADDITIONAL_VERSIONS variable can be used to specify a list of
-# boost version numbers that should be taken into account when searching
-# for Boost. Unfortunately boost puts the version number into the
-# actual filename for the libraries, so this variable will certainly be needed
-# in the future when new Boost versions are released.
-#
-# Currently this module searches for the following version numbers:
-# 1.33, 1.33.0, 1.33.1, 1.34, 1.34.0, 1.34.1, 1.35, 1.35.0, 1.35.1,
-# 1.36, 1.36.0, 1.36.1, 1.37, 1.37.0, 1.38, 1.38.0, 1.39, 1.39.0,
-# 1.40, 1.40.0, 1.41, 1.41.0
-#
-# NOTE: If you add a new major 1.x version in Boost_ADDITIONAL_VERSIONS you should
-# add both 1.x and 1.x.0 as shown above.  Official Boost include directories
-# omit the 3rd version number from include paths if it is 0 although not all
-# binary Boost releases do so.
-#
-# SET(Boost_ADDITIONAL_VERSIONS "1.78" "1.78.0" "1.79" "1.79.0")
-#
-# ===================================== ============= ========================
-#
-# Variables used by this module, they can change the default behaviour and
-# need to be set before calling find_package:
-#
-#   Boost_USE_MULTITHREADED      Can be set to OFF to use the non-multithreaded
-#                                boost libraries.  If not specified, defaults
-#                                to ON.
-#
-#   Boost_USE_STATIC_LIBS        Can be set to ON to force the use of the static
-#                                boost libraries. Defaults to OFF.
-#
-# Other Variables used by this module which you may want to set.
-#
-#   Boost_ADDITIONAL_VERSIONS    A list of version numbers to use for searching
-#                                the boost include directory.  Please see
-#                                the documentation above regarding this
-#                                annoying, but necessary variable :(
-#
-#   Boost_DEBUG                  Set this to TRUE to enable debugging output
-#                                of FindBoost.cmake if you are having problems.
-#                                Please enable this before filing any bug
-#                                reports.
-#
-#   Boost_DETAILED_FAILURE_MSG   FindBoost doesn't output detailed information
-#                                about why it failed or how to fix the problem
-#                                unless this is set to TRUE or the REQUIRED
-#                                keyword is specified in find_package().
-#                                  [Since CMake 2.8.0]
-# 
-#   Boost_COMPILER               Set this to the compiler suffix used by Boost
-#                                (e.g. "-gcc43") if FindBoost has problems finding
-#                                the proper Boost installation
-#
-# These last three variables are available also as environment variables:
-#
-#   BOOST_ROOT or BOOSTROOT      The preferred installation prefix for searching for
-#                                Boost.  Set this if the module has problems finding
-#                                the proper Boost installation.
-#
-#   BOOST_INCLUDEDIR             Set this to the include directory of Boost, if the
-#                                module has problems finding the proper Boost installation
-#
-#   BOOST_LIBRARYDIR             Set this to the lib directory of Boost, if the
-#                                module has problems finding the proper Boost installation
-#
-# Variables defined by this module:
-#
-#   Boost_FOUND                         System has Boost, this means the include dir was
-#                                       found, as well as all the libraries specified in
-#                                       the COMPONENTS list.
-#
-#   Boost_INCLUDE_DIRS                  Boost include directories: not cached
-#
-#   Boost_INCLUDE_DIR                   This is almost the same as above, but this one is
-#                                       cached and may be modified by advanced users
-#
-#   Boost_LIBRARIES                     Link to these to use the Boost libraries that you
-#                                       specified: not cached
-#
-#   Boost_LIBRARY_DIRS                  The path to where the Boost library files are.
-#
-#   Boost_VERSION                       The version number of the boost libraries that
-#                                       have been found, same as in version.hpp from Boost
-#
-#   Boost_LIB_VERSION                   The version number in filename form as
-#                                       it's appended to the library filenames
-#
-#   Boost_MAJOR_VERSION                 major version number of boost
-#   Boost_MINOR_VERSION                 minor version number of boost
-#   Boost_SUBMINOR_VERSION              subminor version number of boost
-#
-#   Boost_LIB_DIAGNOSTIC_DEFINITIONS    [WIN32 Only] You can call
-#                                       add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
-#                                       to have diagnostic information about Boost's
-#                                       automatic linking outputted during compilation time.
-#
-# For each component you specify in find_package(), the following (UPPER-CASE)
-# variables are set.  You can use these variables if you would like to pick and
-# choose components for your targets instead of just using Boost_LIBRARIES.
-#
-#   Boost_${COMPONENT}_FOUND            True IF the Boost library "component" was found.
-#
-#   Boost_${COMPONENT}_LIBRARY          Contains the libraries for the specified Boost
-#                                       "component" (includes debug and optimized keywords
-#                                       when needed).
-
-#=============================================================================
-# Copyright 2006-2009 Kitware, Inc.
-# Copyright 2006-2008 Andreas Schneider <mail at cynapses.org>
-# Copyright 2007      Wengo
-# Copyright 2007      Mike Jackson
-# Copyright 2008      Andreas Pakulat <apaku at gmx.de>
-# Copyright 2008-2009 Philip Lowman <philip at yhbt.com>
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distributed this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-#-------------------------------------------------------------------------------
-#  FindBoost functions & macros
-#
-############################################
-#
-# Check the existence of the libraries.
-#
-############################################
-# This macro was taken directly from the FindQt4.cmake file that is included
-# with the CMake distribution. This is NOT my work. All work was done by the
-# original authors of the FindQt4.cmake file. Only minor modifications were
-# made to remove references to Qt and make this file more generally applicable
-# And ELSE/ENDIF pairs were removed for readability.
-#########################################################################
-
-MACRO (_Boost_ADJUST_LIB_VARS basename)
-  IF (Boost_INCLUDE_DIR )
-    IF (Boost_${basename}_LIBRARY_DEBUG AND Boost_${basename}_LIBRARY_RELEASE)
-      # if the generator supports configuration types then set
-      # optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value
-      IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
-        SET(Boost_${basename}_LIBRARY optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG})
-      ELSE()
-        # if there are no configuration types and CMAKE_BUILD_TYPE has no value
-        # then just use the release libraries
-        SET(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} )
-      ENDIF()
-      # FIXME: This probably should be set for both cases
-      SET(Boost_${basename}_LIBRARIES optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG})
-    ENDIF()
-
-    # if only the release version was found, set the debug variable also to the release version
-    IF (Boost_${basename}_LIBRARY_RELEASE AND NOT Boost_${basename}_LIBRARY_DEBUG)
-      SET(Boost_${basename}_LIBRARY_DEBUG ${Boost_${basename}_LIBRARY_RELEASE})
-      SET(Boost_${basename}_LIBRARY       ${Boost_${basename}_LIBRARY_RELEASE})
-      SET(Boost_${basename}_LIBRARIES     ${Boost_${basename}_LIBRARY_RELEASE})
-    ENDIF()
-
-    # if only the debug version was found, set the release variable also to the debug version
-    IF (Boost_${basename}_LIBRARY_DEBUG AND NOT Boost_${basename}_LIBRARY_RELEASE)
-      SET(Boost_${basename}_LIBRARY_RELEASE ${Boost_${basename}_LIBRARY_DEBUG})
-      SET(Boost_${basename}_LIBRARY         ${Boost_${basename}_LIBRARY_DEBUG})
-      SET(Boost_${basename}_LIBRARIES       ${Boost_${basename}_LIBRARY_DEBUG})
-    ENDIF()
-    
-    IF (Boost_${basename}_LIBRARY)
-      set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY} CACHE FILEPATH "The Boost ${basename} library")
-
-      # Remove superfluous "debug" / "optimized" keywords from
-      # Boost_LIBRARY_DIRS
-      FOREACH(_boost_my_lib ${Boost_${basename}_LIBRARY})
-        GET_FILENAME_COMPONENT(_boost_my_lib_path "${_boost_my_lib}" PATH)
-        LIST(APPEND Boost_LIBRARY_DIRS ${_boost_my_lib_path})
-      ENDFOREACH()
-      LIST(REMOVE_DUPLICATES Boost_LIBRARY_DIRS)
-
-      set(Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIRS} CACHE FILEPATH "Boost library directory")
-      SET(Boost_${basename}_FOUND ON CACHE INTERNAL "Whether the Boost ${basename} library found")
-    ENDIF(Boost_${basename}_LIBRARY)
-
-  ENDIF (Boost_INCLUDE_DIR )
-  # Make variables changeble to the advanced user
-  MARK_AS_ADVANCED(
-      Boost_${basename}_LIBRARY
-      Boost_${basename}_LIBRARY_RELEASE
-      Boost_${basename}_LIBRARY_DEBUG
-  )
-ENDMACRO (_Boost_ADJUST_LIB_VARS)
-
-#-------------------------------------------------------------------------------
-
-#
-# Runs compiler with "-dumpversion" and parses major/minor
-# version with a regex.
-#
-FUNCTION(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION)
-
-  EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
-    ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
-    OUTPUT_VARIABLE _boost_COMPILER_VERSION
-  )
-  STRING(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
-    _boost_COMPILER_VERSION ${_boost_COMPILER_VERSION})
-
-  SET(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE)
-ENDFUNCTION()
-
-#
-# A convenience function for marking desired components
-# as found or not
-#
-function(_Boost_MARK_COMPONENTS_FOUND _yes_or_no)
-  foreach(COMPONENT ${Boost_FIND_COMPONENTS})
-    string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
-    set(Boost_${UPPERCOMPONENT}_FOUND ${_yes_or_no} CACHE INTERNAL "Whether the Boost ${COMPONENT} library found" FORCE)
-  endforeach()
-endfunction()
-
-#
-# End functions/macros
-#  
-#-------------------------------------------------------------------------------
-
-
-
-
-IF(NOT DEFINED Boost_USE_MULTITHREADED)
-    SET(Boost_USE_MULTITHREADED TRUE)
-ENDIF()
-
-if(Boost_FIND_VERSION_EXACT)
-  # The version may appear in a directory with or without the patch
-  # level, even when the patch level is non-zero.
-  set(_boost_TEST_VERSIONS
-    "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}.${Boost_FIND_VERSION_PATCH}"
-    "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
-else(Boost_FIND_VERSION_EXACT)
-  # The user has not requested an exact version.  Among known
-  # versions, find those that are acceptable to the user request.
-  set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
-    "1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37"
-    "1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0"
-    "1.34" "1.33.1" "1.33.0" "1.33")
-  set(_boost_TEST_VERSIONS)
-  if(Boost_FIND_VERSION)
-    set(_Boost_FIND_VERSION_SHORT "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
-    # Select acceptable versions.
-    foreach(version ${_Boost_KNOWN_VERSIONS})
-      if(NOT "${version}" VERSION_LESS "${Boost_FIND_VERSION}")
-        # This version is high enough.
-        list(APPEND _boost_TEST_VERSIONS "${version}")
-      elseif("${version}.99" VERSION_EQUAL "${_Boost_FIND_VERSION_SHORT}.99")
-        # This version is a short-form for the requested version with
-        # the patch level dropped.
-        list(APPEND _boost_TEST_VERSIONS "${version}")
-      endif()
-    endforeach(version)
-  else(Boost_FIND_VERSION)
-    # Any version is acceptable.
-    set(_boost_TEST_VERSIONS "${_Boost_KNOWN_VERSIONS}")
-  endif(Boost_FIND_VERSION)
-endif(Boost_FIND_VERSION_EXACT)
-
-# The reason that we failed to find Boost. This will be set to a
-# user-friendly message when we fail to find some necessary piece of
-# Boost.
-set(Boost_ERROR_REASON)
-
-SET( _boost_IN_CACHE TRUE)
-IF(Boost_INCLUDE_DIR)
-
-  # On versions < 1.35, remove the System library from the considered list
-  # since it wasn't added until 1.35.
-  if(Boost_VERSION AND Boost_FIND_COMPONENTS)
-     math(EXPR _boost_maj "${Boost_VERSION} / 100000")
-     math(EXPR _boost_min "${Boost_VERSION} / 100 % 1000")
-     if(${_boost_maj}.${_boost_min} VERSION_LESS 1.35)
-       list(REMOVE_ITEM Boost_FIND_COMPONENTS system)
-     endif()
-  endif()
-
-  FOREACH(COMPONENT ${Boost_FIND_COMPONENTS})
-    STRING(TOUPPER ${COMPONENT} COMPONENT)
-    IF(NOT Boost_${COMPONENT}_FOUND)
-      SET( _boost_IN_CACHE FALSE)
-    ENDIF(NOT Boost_${COMPONENT}_FOUND)
-  ENDFOREACH(COMPONENT)
-ELSE(Boost_INCLUDE_DIR)
-  SET( _boost_IN_CACHE FALSE)
-ENDIF(Boost_INCLUDE_DIR)
-
-IF (_boost_IN_CACHE)
-  # in cache already
-  SET(Boost_FOUND TRUE)
-  FOREACH(COMPONENT ${Boost_FIND_COMPONENTS})
-    STRING(TOUPPER ${COMPONENT} COMPONENT)
-    _Boost_ADJUST_LIB_VARS( ${COMPONENT} )
-    SET(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${COMPONENT}_LIBRARY})
-  ENDFOREACH(COMPONENT)
-  SET(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR})
-  IF(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0")
-    MATH(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
-    MATH(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
-    MATH(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
-  ENDIF(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0")
-  if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "boost ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION} "
-                     "is already in the cache.  For debugging messages, please clear the cache.")
-  endif()
-ELSE (_boost_IN_CACHE)
-  # Need to search for boost
-  if(Boost_DEBUG)
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Boost not in cache")
-    # Output some of their choices
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Boost_USE_MULTITHREADED = ${Boost_USE_MULTITHREADED}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Boost_USE_STATIC_LIBS = ${Boost_USE_STATIC_LIBS}")
-  endif()
-
-  IF(WIN32)
-    # In windows, automatic linking is performed, so you do not have
-    # to specify the libraries.  If you are linking to a dynamic
-    # runtime, then you can choose to link to either a static or a
-    # dynamic Boost library, the default is to do a static link.  You
-    # can alter this for a specific library "whatever" by defining
-    # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be
-    # linked dynamically.  Alternatively you can force all Boost
-    # libraries to dynamic link by defining BOOST_ALL_DYN_LINK.
-  
-    # This feature can be disabled for Boost library "whatever" by
-    # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining
-    # BOOST_ALL_NO_LIB.
-  
-    # If you want to observe which libraries are being linked against
-    # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking
-    # code to emit a #pragma message each time a library is selected
-    # for linking.
-    SET(Boost_LIB_DIAGNOSTIC_DEFINITIONS 
-      "-DBOOST_LIB_DIAGNOSTIC" CACHE STRING "Boost diagnostic define")
-  ENDIF(WIN32)
-
-  SET(_boost_INCLUDE_SEARCH_DIRS
-    C:/boost/include
-    C:/boost
-    "$ENV{ProgramFiles}/boost/include"
-    "$ENV{ProgramFiles}/boost"
-    /sw/local/include
-  )
-
-  # If BOOST_ROOT was defined in the environment, use it.
-  if (NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "")
-    set(BOOST_ROOT $ENV{BOOST_ROOT})
-  endif(NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "")
-
-  # If BOOSTROOT was defined in the environment, use it.
-  if (NOT BOOST_ROOT AND NOT $ENV{BOOSTROOT} STREQUAL "")
-    set(BOOST_ROOT $ENV{BOOSTROOT})
-  endif(NOT BOOST_ROOT AND NOT $ENV{BOOSTROOT} STREQUAL "")
-
-  # If BOOST_INCLUDEDIR was defined in the environment, use it.
-  IF( NOT $ENV{BOOST_INCLUDEDIR} STREQUAL "" )
-    set(BOOST_INCLUDEDIR $ENV{BOOST_INCLUDEDIR})
-  ENDIF( NOT $ENV{BOOST_INCLUDEDIR} STREQUAL "" )
-  
-  # If BOOST_LIBRARYDIR was defined in the environment, use it.
-  IF( NOT $ENV{BOOST_LIBRARYDIR} STREQUAL "" )
-    set(BOOST_LIBRARYDIR $ENV{BOOST_LIBRARYDIR})
-  ENDIF( NOT $ENV{BOOST_LIBRARYDIR} STREQUAL "" )
-  
-  IF( BOOST_ROOT )
-    file(TO_CMAKE_PATH ${BOOST_ROOT} BOOST_ROOT)
-  ENDIF( BOOST_ROOT )
-
-  if(Boost_DEBUG)
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Declared as CMake or Environmental Variables:")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "  BOOST_ROOT = ${BOOST_ROOT}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "  BOOST_INCLUDEDIR = ${BOOST_INCLUDEDIR}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "  BOOST_LIBRARYDIR = ${BOOST_LIBRARYDIR}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
-  endif()
-
-  IF( BOOST_ROOT )
-    SET(_boost_INCLUDE_SEARCH_DIRS 
-      ${BOOST_ROOT}/include 
-      ${BOOST_ROOT}
-      ${_boost_INCLUDE_SEARCH_DIRS})
-  ENDIF( BOOST_ROOT )
-
-  IF( BOOST_INCLUDEDIR )
-    file(TO_CMAKE_PATH ${BOOST_INCLUDEDIR} BOOST_INCLUDEDIR)
-    SET(_boost_INCLUDE_SEARCH_DIRS 
-      ${BOOST_INCLUDEDIR} ${_boost_INCLUDE_SEARCH_DIRS})
-  ENDIF( BOOST_INCLUDEDIR )
-
-  # ------------------------------------------------------------------------
-  #  Search for Boost include DIR 
-  # ------------------------------------------------------------------------
-  # Try to find Boost by stepping backwards through the Boost versions
-  # we know about.
-  IF( NOT Boost_INCLUDE_DIR )
-    # Build a list of path suffixes for each version.
-    SET(_boost_PATH_SUFFIXES)
-    FOREACH(_boost_VER ${_boost_TEST_VERSIONS})
-      # Add in a path suffix, based on the required version, ideally
-      # we could read this from version.hpp, but for that to work we'd
-      # need to know the include dir already
-      set(_boost_BOOSTIFIED_VERSION)
-
-      # Transform 1.35 => 1_35 and 1.36.0 => 1_36_0
-      IF(_boost_VER MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
-          STRING(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1_\\2_\\3" 
-            _boost_BOOSTIFIED_VERSION ${_boost_VER})
-      ELSEIF(_boost_VER MATCHES "[0-9]+\\.[0-9]+")
-          STRING(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1_\\2" 
-            _boost_BOOSTIFIED_VERSION ${_boost_VER})
-      ENDIF()
-      
-      list(APPEND _boost_PATH_SUFFIXES "boost-${_boost_BOOSTIFIED_VERSION}")
-      if(WIN32)
-        # For BoostPro's underscores (and others?)
-        list(APPEND _boost_PATH_SUFFIXES "boost_${_boost_BOOSTIFIED_VERSION}")
-      endif()
-
-    ENDFOREACH(_boost_VER)
-      
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "Include debugging info:")
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "  _boost_INCLUDE_SEARCH_DIRS = ${_boost_INCLUDE_SEARCH_DIRS}")
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "  _boost_PATH_SUFFIXES = ${_boost_PATH_SUFFIXES}")
-    endif()
-
-    # Look for a standard boost header file.
-    FIND_PATH(Boost_INCLUDE_DIR
-      NAMES         boost/config.hpp
-      HINTS         ${_boost_INCLUDE_SEARCH_DIRS}
-      PATH_SUFFIXES ${_boost_PATH_SUFFIXES}
-      )
-  ENDIF( NOT Boost_INCLUDE_DIR )
-  
-  # ------------------------------------------------------------------------
-  #  Extract version information from version.hpp
-  # ------------------------------------------------------------------------
-
-  IF(Boost_INCLUDE_DIR)
-    # Extract Boost_VERSION and Boost_LIB_VERSION from version.hpp
-    # Read the whole file:
-    #
-    SET(BOOST_VERSION 0)
-    SET(BOOST_LIB_VERSION "")
-    FILE(READ "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS)
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp")
-    endif()
-  
-    STRING(REGEX REPLACE ".*#define BOOST_VERSION ([0-9]+).*" "\\1" Boost_VERSION "${_boost_VERSION_HPP_CONTENTS}")
-    STRING(REGEX REPLACE ".*#define BOOST_LIB_VERSION \"([0-9_]+)\".*" "\\1" Boost_LIB_VERSION "${_boost_VERSION_HPP_CONTENTS}")
-  
-    SET(Boost_LIB_VERSION ${Boost_LIB_VERSION} CACHE INTERNAL "The library version string for boost libraries")
-    SET(Boost_VERSION ${Boost_VERSION} CACHE INTERNAL "The version number for boost libraries")
-    
-    IF(NOT "${Boost_VERSION}" STREQUAL "0")
-      MATH(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
-      MATH(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
-      MATH(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
-
-      set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}\nBoost include path: ${Boost_INCLUDE_DIR}")
-    ENDIF(NOT "${Boost_VERSION}" STREQUAL "0")
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "version.hpp reveals boost "
-                     "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
-    endif()
-  ELSE(Boost_INCLUDE_DIR)
-    set(Boost_ERROR_REASON
-      "${Boost_ERROR_REASON}Unable to find the Boost header files. Please set BOOST_ROOT to the root directory containing Boost or BOOST_INCLUDEDIR to the directory containing Boost's headers.")
-  ENDIF(Boost_INCLUDE_DIR)
-  
-  # ------------------------------------------------------------------------
-  #  Suffix initialization and compiler suffix detection.
-  # ------------------------------------------------------------------------
-
-  # Setting some more suffixes for the library
-  SET (Boost_LIB_PREFIX "")
-  if ( WIN32 AND Boost_USE_STATIC_LIBS )
-    SET (Boost_LIB_PREFIX "lib")
-  endif()
-
-  if (Boost_COMPILER)
-    set(_boost_COMPILER ${Boost_COMPILER})
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "using user-specified Boost_COMPILER = ${_boost_COMPILER}")
-    endif()
-  else(Boost_COMPILER)
-    # Attempt to guess the compiler suffix
-    # NOTE: this is not perfect yet, if you experience any issues
-    # please report them and use the Boost_COMPILER variable
-    # to work around the problems.
-    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel"
-        OR "${CMAKE_CXX_COMPILER}" MATCHES "icl" 
-        OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
-      if(WIN32)
-        set (_boost_COMPILER "-iw")
-      else()
-        set (_boost_COMPILER "-il")
-      endif()
-    elseif (MSVC90)
-      SET (_boost_COMPILER "-vc90")
-    elseif (MSVC10)
-      SET (_boost_COMPILER "-vc100")
-    elseif (MSVC80)
-      SET (_boost_COMPILER "-vc80")
-    elseif (MSVC71)
-      SET (_boost_COMPILER "-vc71")
-    elseif (MSVC70) # Good luck!
-      SET (_boost_COMPILER "-vc7") # yes, this is correct
-    elseif (MSVC60) # Good luck!
-      SET (_boost_COMPILER "-vc6") # yes, this is correct
-    elseif (BORLAND)
-      SET (_boost_COMPILER "-bcb")
-    elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro")
-      set(_boost_COMPILER "-sw")
-    elseif (MINGW)
-      if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34)
-          SET(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34
-      else()
-        _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION)
-        SET (_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}")
-      endif()
-    elseif (UNIX)
-      if (CMAKE_COMPILER_IS_GNUCXX)
-        if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34)
-          SET(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34
-        else()
-          _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION)
-          # Determine which version of GCC we have.
-          IF(APPLE)
-            IF(Boost_MINOR_VERSION)
-              IF(${Boost_MINOR_VERSION} GREATER 35)
-                # In Boost 1.36.0 and newer, the mangled compiler name used
-                # on Mac OS X/Darwin is "xgcc".
-                SET(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}")
-              ELSE(${Boost_MINOR_VERSION} GREATER 35)
-                # In Boost <= 1.35.0, there is no mangled compiler name for
-                # the Mac OS X/Darwin version of GCC.
-                SET(_boost_COMPILER "")
-              ENDIF(${Boost_MINOR_VERSION} GREATER 35)
-            ELSE(Boost_MINOR_VERSION)
-              # We don't know the Boost version, so assume it's
-              # pre-1.36.0.
-              SET(_boost_COMPILER "")
-            ENDIF(Boost_MINOR_VERSION)
-          ELSE()
-            SET (_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}")
-          ENDIF()
-        endif()
-      endif (CMAKE_COMPILER_IS_GNUCXX)
-    endif()
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-        "guessed _boost_COMPILER = ${_boost_COMPILER}")
-    endif()
-  endif(Boost_COMPILER)
-
-
-  if(${Boost_MINOR_VERSION} AND ${Boost_MINOR_VERSION} GREATER 41 AND NOT WIN32 AND NOT APPLE)
-      set (_boost_MULTITHREADED "")
-  else()
-    SET (_boost_MULTITHREADED "-mt")
-    if( NOT Boost_USE_MULTITHREADED )
-      set (_boost_MULTITHREADED "")
-    endif()
-  endif()
-
-  if(Boost_DEBUG)
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-      "_boost_MULTITHREADED = ${_boost_MULTITHREADED}")
-  endif()
-
-  SET( _boost_STATIC_TAG "")
-  set( _boost_ABI_TAG "")
-  IF (WIN32)
-    IF(MSVC OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
-            OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
-      SET (_boost_ABI_TAG "g")
-    ENDIF()
-    IF( Boost_USE_STATIC_LIBS )
-      SET( _boost_STATIC_TAG "-s")
-    ENDIF( Boost_USE_STATIC_LIBS )
-  ENDIF(WIN32)
-  SET (_boost_ABI_TAG "${_boost_ABI_TAG}d")
-  if(Boost_DEBUG)
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-      "_boost_STATIC_TAG = ${_boost_STATIC_TAG}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-      "_boost_ABI_TAG = ${_boost_ABI_TAG}")
-  endif()
-
-  # ------------------------------------------------------------------------
-  #  Begin finding boost libraries
-  # ------------------------------------------------------------------------
-
-  SET(_boost_LIBRARIES_SEARCH_DIRS
-    ${Boost_INCLUDE_DIR}/lib
-    ${Boost_INCLUDE_DIR}/../lib
-    C:/boost/lib
-    C:/boost
-    "$ENV{ProgramFiles}/boost/boost_${Boost_MAJOR_VERSION}_${Boost_MINOR_VERSION}_${Boost_SUBMINOR_VERSION}/lib"
-    "$ENV{ProgramFiles}/boost/boost_${Boost_MAJOR_VERSION}_${Boost_MINOR_VERSION}/lib"
-    "$ENV{ProgramFiles}/boost/lib"
-    "$ENV{ProgramFiles}/boost"
-    /sw/local/lib
-  )
-  IF( BOOST_ROOT )
-    SET(_boost_LIBRARIES_SEARCH_DIRS 
-      ${BOOST_ROOT}/lib 
-      ${BOOST_ROOT}/stage/lib 
-      ${_boost_LIBRARIES_SEARCH_DIRS})
-  ENDIF( BOOST_ROOT )
-
-  IF( BOOST_LIBRARYDIR )
-    file(TO_CMAKE_PATH ${BOOST_LIBRARYDIR} BOOST_LIBRARYDIR)
-    SET(_boost_LIBRARIES_SEARCH_DIRS 
-      ${BOOST_LIBRARYDIR} ${_boost_LIBRARIES_SEARCH_DIRS})
-  ENDIF( BOOST_LIBRARYDIR )
-
-  if(Boost_DEBUG)
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-      "_boost_LIBRARIES_SEARCH_DIRS = ${_boost_LIBRARIES_SEARCH_DIRS}")
-  endif()
-
-  FOREACH(COMPONENT ${Boost_FIND_COMPONENTS})
-    STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
-    SET( Boost_${UPPERCOMPONENT}_LIBRARY "Boost_${UPPERCOMPONENT}_LIBRARY-NOTFOUND" )
-    SET( Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE-NOTFOUND" )
-    SET( Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG-NOTFOUND")
-
-    # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
-    IF( Boost_USE_STATIC_LIBS )
-      SET( _boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
-      IF(WIN32)
-        SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
-      ELSE(WIN32)
-        SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
-      ENDIF(WIN32)
-    ENDIF( Boost_USE_STATIC_LIBS )
-
-    FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
-        NAMES  ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}-${Boost_LIB_VERSION}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_STATIC_TAG}-${Boost_LIB_VERSION}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}-${Boost_LIB_VERSION}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}-${Boost_LIB_VERSION}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}
-        HINTS  ${_boost_LIBRARIES_SEARCH_DIRS}
-    )
-
-    FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG
-        NAMES  ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}-${_boost_ABI_TAG}-${Boost_LIB_VERSION}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_STATIC_TAG}${_boost_ABI_TAG}-${Boost_LIB_VERSION}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}-${_boost_ABI_TAG}-${Boost_LIB_VERSION}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}${_boost_ABI_TAG}-${Boost_LIB_VERSION}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}-${_boost_ABI_TAG}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}${_boost_ABI_TAG}
-               ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_boost_ABI_TAG}
-        HINTS  ${_boost_LIBRARIES_SEARCH_DIRS}
-    )
-
-    _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT})
-    IF( Boost_USE_STATIC_LIBS )
-      SET(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
-    ENDIF( Boost_USE_STATIC_LIBS )
-  ENDFOREACH(COMPONENT)
-  # ------------------------------------------------------------------------
-  #  End finding boost libraries
-  # ------------------------------------------------------------------------
-
-  SET(Boost_INCLUDE_DIRS
-    ${Boost_INCLUDE_DIR}
-  )
-
-  SET(Boost_FOUND FALSE)
-  IF(Boost_INCLUDE_DIR)
-    SET( Boost_FOUND TRUE )
-
-    # Check the version of Boost against the requested version.
-    if (Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR)
-      message(SEND_ERROR "When requesting a specific version of Boost, you must provide at least the major and minor version numbers, e.g., 1.34")
-    endif (Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR)
-    if(Boost_MAJOR_VERSION LESS "${Boost_FIND_VERSION_MAJOR}" )
-      set( Boost_FOUND FALSE )
-      set(_Boost_VERSION_AGE "old")
-    elseif(Boost_MAJOR_VERSION EQUAL "${Boost_FIND_VERSION_MAJOR}" )
-      if(Boost_MINOR_VERSION LESS "${Boost_FIND_VERSION_MINOR}" )
-        set( Boost_FOUND FALSE )
-        set(_Boost_VERSION_AGE "old")
-      elseif(Boost_MINOR_VERSION EQUAL "${Boost_FIND_VERSION_MINOR}" )
-        if( Boost_FIND_VERSION_PATCH AND Boost_SUBMINOR_VERSION LESS "${Boost_FIND_VERSION_PATCH}" )
-          set( Boost_FOUND FALSE )
-          set(_Boost_VERSION_AGE "old")
-        endif( Boost_FIND_VERSION_PATCH AND Boost_SUBMINOR_VERSION LESS "${Boost_FIND_VERSION_PATCH}" )
-      endif( Boost_MINOR_VERSION LESS "${Boost_FIND_VERSION_MINOR}" )
-    endif( Boost_MAJOR_VERSION LESS "${Boost_FIND_VERSION_MAJOR}" )
-
-    if (NOT Boost_FOUND)
-      _Boost_MARK_COMPONENTS_FOUND(OFF)
-    endif()
-
-    if (Boost_FOUND AND Boost_FIND_VERSION_EXACT)
-      # If the user requested an exact version of Boost, check
-      # that. We already know that the Boost version we have is >= the
-      # requested version.
-      set(_Boost_VERSION_AGE "new")
-
-      # If the user didn't specify a patchlevel, it's 0.
-      if (NOT Boost_FIND_VERSION_PATCH)
-        set(Boost_FIND_VERSION_PATCH 0)
-      endif (NOT Boost_FIND_VERSION_PATCH)
-      
-      # We'll set Boost_FOUND true again if we have an exact version match.
-      set(Boost_FOUND FALSE)
-      _Boost_MARK_COMPONENTS_FOUND(OFF)
-      if(Boost_MAJOR_VERSION EQUAL "${Boost_FIND_VERSION_MAJOR}" )
-        if(Boost_MINOR_VERSION EQUAL "${Boost_FIND_VERSION_MINOR}" )
-          if(Boost_SUBMINOR_VERSION EQUAL "${Boost_FIND_VERSION_PATCH}" )
-            set( Boost_FOUND TRUE )
-            _Boost_MARK_COMPONENTS_FOUND(ON)
-          endif(Boost_SUBMINOR_VERSION EQUAL "${Boost_FIND_VERSION_PATCH}" )
-        endif( Boost_MINOR_VERSION EQUAL "${Boost_FIND_VERSION_MINOR}" )
-      endif( Boost_MAJOR_VERSION EQUAL "${Boost_FIND_VERSION_MAJOR}" )
-    endif (Boost_FOUND AND Boost_FIND_VERSION_EXACT)
-
-    if(NOT Boost_FOUND)
-      # State that we found a version of Boost that is too new or too old.
-      set(Boost_ERROR_REASON
-        "${Boost_ERROR_REASON}\nDetected version of Boost is too ${_Boost_VERSION_AGE}. Requested version was ${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
-      if (Boost_FIND_VERSION_PATCH)
-        set(Boost_ERROR_REASON 
-          "${Boost_ERROR_REASON}.${Boost_FIND_VERSION_PATCH}")
-      endif (Boost_FIND_VERSION_PATCH)
-      if (NOT Boost_FIND_VERSION_EXACT)
-        set(Boost_ERROR_REASON "${Boost_ERROR_REASON} (or newer)")
-      endif (NOT Boost_FIND_VERSION_EXACT)
-      set(Boost_ERROR_REASON "${Boost_ERROR_REASON}.")
-    endif (NOT Boost_FOUND)
-
-    # Always check for missing components
-    set(_boost_CHECKED_COMPONENT FALSE)
-    set(_Boost_MISSING_COMPONENTS "")
-    foreach(COMPONENT ${Boost_FIND_COMPONENTS})
-      string(TOUPPER ${COMPONENT} COMPONENT)
-      set(_boost_CHECKED_COMPONENT TRUE)
-      if(NOT Boost_${COMPONENT}_FOUND)
-        string(TOLOWER ${COMPONENT} COMPONENT)
-        list(APPEND _Boost_MISSING_COMPONENTS ${COMPONENT})
-        set( Boost_FOUND FALSE)
-      endif(NOT Boost_${COMPONENT}_FOUND)
-    endforeach(COMPONENT)
-
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] Boost_FOUND = ${Boost_FOUND}")
-    endif()
-
-    if (_Boost_MISSING_COMPONENTS)
-      # We were unable to find some libraries, so generate a sensible
-      # error message that lists the libraries we were unable to find.
-      set(Boost_ERROR_REASON
-        "${Boost_ERROR_REASON}\nThe following Boost libraries could not be found:\n")
-      foreach(COMPONENT ${_Boost_MISSING_COMPONENTS})
-        set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}        boost_${COMPONENT}\n")
-      endforeach(COMPONENT)
-
-      list(LENGTH Boost_FIND_COMPONENTS Boost_NUM_COMPONENTS_WANTED)
-      list(LENGTH _Boost_MISSING_COMPONENTS Boost_NUM_MISSING_COMPONENTS)
-      if (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
-        set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}No Boost libraries were found. You may need to set Boost_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
-      else (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
-        set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}Some (but not all) of the required Boost libraries were found. You may need to install these additional Boost libraries. Alternatively, set Boost_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
-      endif (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
-    endif (_Boost_MISSING_COMPONENTS)
-
-    IF( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
-      # Compatibility Code for backwards compatibility with CMake
-      # 2.4's FindBoost module.
-
-      # Look for the boost library path.
-      # Note that the user may not have installed any libraries
-      # so it is quite possible the Boost_LIBRARY_PATH may not exist.
-      SET(_boost_LIB_DIR ${Boost_INCLUDE_DIR})
-    
-      IF("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+")
-        GET_FILENAME_COMPONENT(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
-      ENDIF ("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+")
-    
-      IF("${_boost_LIB_DIR}" MATCHES "/include$")
-        # Strip off the trailing "/include" in the path.
-        GET_FILENAME_COMPONENT(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
-      ENDIF("${_boost_LIB_DIR}" MATCHES "/include$")
-    
-      IF(EXISTS "${_boost_LIB_DIR}/lib")
-        SET (_boost_LIB_DIR ${_boost_LIB_DIR}/lib)
-      ELSE(EXISTS "${_boost_LIB_DIR}/lib")
-        IF(EXISTS "${_boost_LIB_DIR}/stage/lib")
-          SET(_boost_LIB_DIR ${_boost_LIB_DIR}/stage/lib)
-        ELSE(EXISTS "${_boost_LIB_DIR}/stage/lib")
-          SET(_boost_LIB_DIR "")
-        ENDIF(EXISTS "${_boost_LIB_DIR}/stage/lib")
-      ENDIF(EXISTS "${_boost_LIB_DIR}/lib")
-    
-      IF(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}")
-        SET(Boost_LIBRARY_DIRS ${_boost_LIB_DIR} CACHE FILEPATH "Boost library directory")
-      ENDIF(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}")
-
-    ENDIF( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
-
-  ELSE(Boost_INCLUDE_DIR)
-    SET( Boost_FOUND FALSE)
-  ENDIF(Boost_INCLUDE_DIR)
-
-  IF (Boost_FOUND)
-      IF (NOT Boost_FIND_QUIETLY)
-        MESSAGE(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
-        if(Boost_FIND_COMPONENTS)
-          message(STATUS "Found the following Boost libraries:")
-        endif()
-      ENDIF(NOT Boost_FIND_QUIETLY)
-      FOREACH ( COMPONENT  ${Boost_FIND_COMPONENTS} )
-        STRING( TOUPPER ${COMPONENT} UPPERCOMPONENT )
-        IF ( Boost_${UPPERCOMPONENT}_FOUND )
-          IF (NOT Boost_FIND_QUIETLY)
-            MESSAGE (STATUS "  ${COMPONENT}")
-          ENDIF(NOT Boost_FIND_QUIETLY)
-          SET(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${UPPERCOMPONENT}_LIBRARY})
-        ENDIF ( Boost_${UPPERCOMPONENT}_FOUND )
-      ENDFOREACH(COMPONENT)
-  else()
-    if(Boost_FIND_REQUIRED)
-      message(SEND_ERROR "Unable to find the requested Boost libraries.\n${Boost_ERROR_REASON}")
-    else()
-      if(NOT Boost_FIND_QUIETLY)
-        # we opt not to automatically output Boost_ERROR_REASON here as
-        # it could be quite lengthy and somewhat imposing in it's requests
-        # Since Boost is not always a required dependency we'll leave this
-        # up to the end-user.
-        if(Boost_DEBUG OR Boost_DETAILED_FAILURE_MSG)
-          message(STATUS "Could NOT find Boost\n${Boost_ERROR_REASON}")
-        else()
-          message(STATUS "Could NOT find Boost")
-        endif()
-      endif()
-    endif(Boost_FIND_REQUIRED)
-  endif()
-
-  # show the Boost_INCLUDE_DIRS AND Boost_LIBRARIES variables only in the advanced view
-  MARK_AS_ADVANCED(Boost_INCLUDE_DIR
-      Boost_INCLUDE_DIRS
-      Boost_LIBRARY_DIRS
-  )
-ENDIF(_boost_IN_CACHE)
-
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1cb6f3a..d880567 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,7 @@ if(NOT CMAKE_BUILD_TYPE)
 	set(CMAKE_BUILD_TYPE "Release")
 endif()
 
-#set(CMAKE_VERBOSE_MAKEFILE 1)
+set(CMAKE_MACOSX_RPATH ON)
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
 
 file(READ "${CMAKE_CURRENT_SOURCE_DIR}/src/version.hpp" _cg3_VERSION_FILE)
@@ -40,17 +40,16 @@ if(MSVC)
 	add_definitions(-DUNICODE -D_UNICODE -D_SECURE_SCL=0 -D_ITERATOR_DEBUG_LEVEL=0 -D_CRT_SECURE_NO_DEPRECATE -DWIN32_LEAN_AND_MEAN -DVC_EXTRALEAN -DNOMINMAX)
 	include_directories("${CMAKE_CURRENT_SOURCE_DIR}/win32")
 else()
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-deprecated -fPIC -fvisibility-inlines-hidden")
-	set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
-	set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
-	set(CMAKE_C_FLAGS ${CMAKE_CXX_FLAGS})
-	set(CMAKE_C_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
-	set(CMAKE_C_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
+	set(_FLAGS_COMMON "-Wall -Wextra -Wno-deprecated -Wno-unused-parameter -fPIC")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_FLAGS_COMMON} -fvisibility-inlines-hidden")
+	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g3")
+	set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG")
+	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FLAGS_COMMON}")
+	set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g3")
+	set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -DNDEBUG")
 
 	# Enable C++11 if possible
-	option(OPT_CXX11 "Set to OFF to disable use of C++11" ON)
-	if(OPT_CXX11 AND
-	((CMAKE_COMPILER_IS_GNUCXX AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.6) OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 3.1)))
+	if((CMAKE_COMPILER_IS_GNUCXX AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.6) OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 3.1))
 		message(STATUS "Enabling C++11 for ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
 	endif()
diff --git a/ChangeLog b/ChangeLog
index 112d733..7b5359c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,128 @@
+2015-01-24  tino
+
+	* [r10378] ChangeLog, src/BinaryGrammar.hpp,
+	  src/BinaryGrammar_read.cpp, src/BinaryGrammar_read_10043.cpp,
+	  src/CMakeLists.txt, src/version.hpp: Add support for loading
+	  grammars from revision 10043 upwards
+	* [r10377] compile-profile.sh, scripts/profile-revisions.php,
+	  src/ApertiumApplicator.cpp, src/ApertiumApplicator.hpp,
+	  src/BinaryGrammar.cpp, src/BinaryGrammar.hpp,
+	  src/BinaryGrammar_read.cpp, src/BinaryGrammar_write.cpp,
+	  src/Cohort.cpp, src/Cohort.hpp, src/CohortIterator.cpp,
+	  src/CohortIterator.hpp, src/ContextualTest.cpp,
+	  src/ContextualTest.hpp, src/FSTApplicator.cpp,
+	  src/FSTApplicator.hpp, src/FormatConverter.cpp,
+	  src/FormatConverter.hpp, src/Grammar.cpp, src/Grammar.hpp,
+	  src/GrammarApplicator.cpp, src/GrammarApplicator.hpp,
+	  src/GrammarApplicator_matchSet.cpp,
+	  src/GrammarApplicator_reflow.cpp,
+	  src/GrammarApplicator_runContextualTest.cpp,
+	  src/GrammarApplicator_runGrammar.cpp,
+	  src/GrammarApplicator_runRules.cpp, src/GrammarWriter.cpp,
+	  src/GrammarWriter.hpp, src/IGrammarParser.hpp,
+	  src/NicelineApplicator.cpp, src/NicelineApplicator.hpp,
+	  src/PlaintextApplicator.cpp, src/PlaintextApplicator.hpp,
+	  src/Reading.cpp, src/Reading.hpp, src/Rule.cpp, src/Rule.hpp,
+	  src/Set.cpp, src/Set.hpp, src/SingleWindow.cpp,
+	  src/SingleWindow.hpp, src/Strings.cpp, src/Strings.hpp,
+	  src/Tag.cpp, src/Tag.hpp, src/TagTrie.hpp, src/TextualParser.cpp,
+	  src/TextualParser.hpp, src/Window.cpp, src/Window.hpp,
+	  src/bloomish.hpp, src/cg3.h, src/cg_comp.cpp, src/cg_conv.cpp,
+	  src/cg_proc.cpp, src/flat_unordered_map.hpp,
+	  src/flat_unordered_set.hpp, src/inlines.hpp,
+	  src/interval_vector.hpp, src/istream.hpp, src/libcg3.cpp,
+	  src/macros.hpp, src/main.cpp, src/options.hpp,
+	  src/options_conv.hpp, src/sorted_vector.hpp, src/stdafx.hpp,
+	  src/test_libcg3.c, src/uextras.cpp, src/uextras.hpp,
+	  src/version.hpp, vapply.sh, vparse.sh: Bump copyright to 2015;
+	  Fix profiling scripts
+	* [r10373] src/GrammarApplicator.cpp, src/GrammarApplicator.hpp,
+	  src/GrammarApplicator_matchSet.cpp, src/flat_unordered_map.hpp:
+	  Take advantage of known set numbers to speed up set-reading cache
+	  to r10297 levels
+	* [r10372] src/ApertiumApplicator.cpp, src/BinaryGrammar.hpp,
+	  src/BinaryGrammar_read.cpp, src/BinaryGrammar_write.cpp,
+	  src/ContextualTest.cpp, src/ContextualTest.hpp,
+	  src/FSTApplicator.cpp, src/Grammar.cpp, src/Grammar.hpp,
+	  src/GrammarApplicator_matchSet.cpp,
+	  src/GrammarApplicator_runGrammar.cpp,
+	  src/GrammarApplicator_runRules.cpp, src/GrammarWriter.cpp,
+	  src/NicelineApplicator.cpp, src/PlaintextApplicator.cpp,
+	  src/Rule.cpp, src/TextualParser.cpp, src/cg_comp.cpp,
+	  src/flat_unordered_set.hpp, src/interval_vector.hpp,
+	  src/main.cpp, src/sorted_vector.hpp: Use set number instead of
+	  hash at runtime; Eliminat some data members and part of the
+	  binary format
+
+2015-01-20  tino
+
+	* [r10367] src/GrammarApplicator.hpp,
+	  src/GrammarApplicator_matchSet.cpp: ...but don't spend 32% extra
+	  time on it.
+	* [r10366] src/GrammarApplicator.hpp,
+	  src/GrammarApplicator_matchSet.cpp, src/flat_unordered_set.hpp:
+	  32bit hash collision seen in the wild - bump cache to 64bit
+
+2014-12-01  tino
+
+	* [r10297] ChangeLog, TODO, src/GrammarApplicator_reflow.cpp,
+	  src/GrammarApplicator_runRules.cpp, src/version.hpp: Handle
+	  mapping tags coming from varstrings
+
+2014-11-11  tino
+
+	* [r10272] ChangeLog, src/GrammarApplicator_runRules.cpp,
+	  src/version.hpp: Fixed Substitute in non-input-order segfault -
+	  how has nobody triggered this before?
+
+2014-11-06  unhammer
+
+	* [r10256] emacs/cg.el: cg--file now buffer-local everywhere, so
+	  grab it before burying buffer
+
+2014-11-05  unhammer
+
+	* [r10255] emacs/cg.el: more keywords; hl symbol-at-point in the
+	  output
+	  
+	  would be nice to highlight any members of LIST-at-point, but
+	  probably need to cache all lists then :-/
+
+2014-11-05  tino
+
+	* [r10254] src/BinaryGrammar_read.cpp: varint branch that reduces
+	  binary filesize by at least 25%; Fix tiny thing in ctest->name
+
+2014-10-29  tino
+
+	* [r10242] manual/installation.xml, src/BinaryGrammar_write.cpp,
+	  src/Grammar.hpp, src/GrammarApplicator_runRules.cpp,
+	  src/stdafx.hpp: Eliminate more std::map; Tell Debians to use
+	  Apertium Nightly; Tell RPMians to use OBS
+
+2014-10-29  unhammer
+
+	* [r10241] emacs/cg.el: beg/end-of-defun fn's; C-M-h now selects a
+	  rule/set
+	  
+	  and C-M-a / C-M-e works as expected
+
+2014-10-21  tino
+
+	* [r10235] src/Grammar.cpp, src/TextualParser.cpp: Error out when
+	  parsing empty ()
+
+2014-10-09  tino
+
+	* [r10218] CMakeLists.txt: Accidentally -fPIC
+	* [r10217] CMake/FindBoost.cmake, CMakeLists.txt,
+	  src/CMakeLists.txt: Mac RPATH and Threads fixes; If C++11 is
+	  possible, require it; Seperate C++ and C flags
+
 2014-10-07  tino
 
+	* [r10195] ChangeLog, src/GrammarApplicator_matchSet.cpp,
+	  src/version.hpp: Forgot the other half
 	* [r10194] ChangeLog, src/GrammarApplicator.hpp,
 	  src/GrammarApplicator_matchSet.cpp,
 	  src/GrammarApplicator_runRules.cpp, src/TagTrie.hpp,
@@ -2418,77 +2541,3 @@
 
 	* [r7630] CMakeLists.txt: cg3
 
-2011-10-28  tino
-
-	* [r7621] scripts/cg3-autobin.pl,
-	  src/GrammarApplicator_matchSet.cpp, src/version.h,
-	  test/T_Unification/expected.txt, test/T_Unification/grammar.txt:
-	  Fixed tag unification of SET sets, I hope...
-
-2011-10-25  tino
-
-	* [r7609] CMakeLists.txt, src/CMakeLists.txt: CPack and Boost fixes
-	* [r7608] scripts/cg3-autobin.pl, src/CMakeLists.txt: Boost
-	  detection fix
-
-2011-10-24  tino
-
-	* [r7607] CMakeLists.txt: CPack test
-
-2011-10-21  tino
-
-	* [r7603] test/T_Unification/expected.txt,
-	  test/T_Unification/grammar.txt: Added test for $$ACESet (1 ACESet
-	  - $$ACESet)
-
-2011-10-19  tino
-
-	* [r7602] scripts/cg3-autobin.pl, src/ApertiumApplicator.cpp,
-	  src/exec-stream.h, src/inlines.h, src/interval_vector.hpp,
-	  src/version.h, src/win/exec-stream-impl.cpp: Line endings &
-	  missing not.
-
-2011-10-18  tino
-
-	* [r7600] scripts/cg3-autobin.pl, src/version.h,
-	  test/T_SubReadings/expected.txt, test/T_SubReadings/grammar.txt,
-	  test/T_SubReadings/input.txt: More sub-reading stuff.
-	* [r7599] scripts/cg3-autobin.pl,
-	  src/GrammarApplicator_runRules.cpp, src/TextualParser.cpp,
-	  src/version.h, test/T_SubReadings/run.pl: More sub-reading stuff.
-	* [r7598] test/T_SubReadings/grammar.txt: If SUB is not followed by
-	  : then it can't be a flag.
-	* [r7597] src/TextualParser.cpp, test/T_SubReadings/grammar.txt: If
-	  SUB is not followed by : then it can't be a flag.
-	* [r7596] src/TextualParser.cpp: If SUB is not followed by : then
-	  it can't be a flag.
-
-2011-10-17  tino
-
-	* [r7594] cg3.g, scripts/cg3-autobin.pl, src/Strings.cpp,
-	  src/Strings.h, src/TextualParser.cpp, src/version.h,
-	  test/T_SubReadings, test/T_SubReadings/expected.txt,
-	  test/T_SubReadings/grammar.txt, test/T_SubReadings/input.txt,
-	  test/T_SubReadings/run.pl, test/runall.pl: Second round of
-	  sub-reading support.
-	* [r7593] cg3.g, scripts/cg3-autobin.pl,
-	  src/ApertiumApplicator.cpp, src/BinaryGrammar_read.cpp,
-	  src/BinaryGrammar_write.cpp, src/ContextualTest.cpp,
-	  src/ContextualTest.h, src/Grammar.cpp, src/Grammar.h,
-	  src/GrammarApplicator.h, src/GrammarApplicator_matchSet.cpp,
-	  src/GrammarApplicator_runContextualTest.cpp,
-	  src/GrammarApplicator_runRules.cpp, src/Reading.cpp,
-	  src/Reading.h, src/Rule.cpp, src/Rule.h, src/Strings.cpp,
-	  src/Strings.h, src/TextualParser.cpp, src/cg_proc.cpp,
-	  src/inlines.h, src/version.h: First round of sub-reading support;
-	  Fewer parse warnings.
-
-2011-10-16  tino
-
-	* [r7590] cg3.g: Line endings...
-	* [r7589] cg3.g: Slightly better BNF
-	* [r7588] cg3.g:
-	* [r7587] cg3.g, src/Set.cpp, src/Set.h, src/Tag.cpp, src/Tag.h,
-	  src/main.cpp, test/T_RegExp/grammar.txt: Almost correct ANTLR BNF
-	  grammar of CG-3
-
diff --git a/TODO b/TODO
index 2585083..9f84daf 100644
--- a/TODO
+++ b/TODO
@@ -55,3 +55,4 @@ ToDo: Better error for APPEND (non-baseform)
 ToDo: \u and \U escapes in textual tags; possibly only varstrings or "tags"
 ToDo: cg-conv should just convert cohorts directly - no need to build whole sentences.
 ToDo: When going from section 1 to section 1+2 the first time, just skip right to the section 2 rules
+ToDo: Rule type MATH, ARITH or similar to manipulate numeric tag values.
diff --git a/compile-profile.sh b/compile-profile.sh
index fe8dc22..b5525dc 100755
--- a/compile-profile.sh
+++ b/compile-profile.sh
@@ -4,10 +4,10 @@ rm -fv gcov/*.gcda
 rm -fv gcov/*.gcno
 rm -fv gcov/vislcg3-c++$CXXV
 cd gcov
-g++ -std=c++$CXXV -DHAVE_BOOST -I~/tmp/boost_1_54_0 -pipe -Wall -Wextra -Wno-deprecated -Wno-unused-local-typedefs -O3 -g3 -fprofile-arcs -ftest-coverage -L/usr/local/lib64 -L/usr/local/lib -ltcmalloc -licuio -licuuc -I../include -I../include/exec-stream ../src/all_vislcg3.cpp -o vislcg3-c++$CXXV
+g++ -std=c++$CXXV -DHAVE_BOOST -pthread -pipe -Wall -Wextra -Wno-deprecated -Wno-unused-local-typedefs -O3 -g3 -fprofile-arcs -ftest-coverage -I../include -I../include/exec-stream ../src/all_vislcg3.cpp -o vislcg3-c++$CXXV -L/usr/lib/x86_64-linux-gnu -licui18n -licudata -licuio -licuuc -ltcmalloc
 cd ..
 mkdir -p gprof
 rm -fv gprof/vislcg3-c++$CXXV
 rm -fv gprof/gmon.out
 cd gprof
-g++ -std=c++$CXXV -DHAVE_BOOST -I~/tmp/boost_1_54_0 -pipe -pg -Wall -Wextra -Wno-deprecated -Wno-unused-local-typedefs -O3 -g3 -L/usr/local/lib64 -L/usr/local/lib -ltcmalloc -licuio -licuuc -I../include -I../include/exec-stream ../src/all_vislcg3.cpp -o vislcg3-c++$CXXV
+g++ -std=c++$CXXV -DHAVE_BOOST -pthread -pipe -pg -Wall -Wextra -Wno-deprecated -Wno-unused-local-typedefs -O3 -g3 -I../include -I../include/exec-stream ../src/all_vislcg3.cpp -o vislcg3-c++$CXXV -L/usr/lib/x86_64-linux-gnu -licui18n -licudata -licuio -licuuc -ltcmalloc
diff --git a/emacs/cg.el b/emacs/cg.el
index bef1151..1f04256 100644
--- a/emacs/cg.el
+++ b/emacs/cg.el
@@ -131,7 +131,10 @@ See also `cg-command' and `cg-pre-pipe'."
 (make-variable-buffer-local 'cg-post-pipe)
 
 (defconst cg-kw-set-list
-  '("LIST" "SET" "TEMPLATE")
+  '("LIST" "SET" "TEMPLATE"
+    ;; These are not sets (and don't have names after the kw) but we
+    ;; have them here to make beginning-of-defun work:
+    "MAPPING-PREFIX" "SOFT-DELIMITERS" "DELIMITERS")
   "Used for indentation, highlighting etc.; don't change without
 re-evaluating `cg-kw-re' (or all of cg.el).")
 (defconst cg-kw-set-re (regexp-opt cg-kw-set-list))
@@ -139,9 +142,10 @@ re-evaluating `cg-kw-re' (or all of cg.el).")
 (defconst cg-kw-rule-list
   '("SUBSTITUTE"
     "IFF"
-    "ADDCOHORT" "ADDCOHORT-AFTER" "ADDCOHORT-BEFORE"
-    "REMCOHORT"
+    "ADDCOHORT" "REMCOHORT"
     "COPY"
+    "MOVE" "SWITCH"
+    "EXTERNAL" "DELIMIT"
     "MAP"    "ADD"
     "UNMAP"
     "SELECT" "REMOVE"
@@ -193,6 +197,8 @@ re-evaluating `cg-kw-re' (or all of cg.el)." )
 				"TARGET"
 				"IF"
 				"AFTER"
+				"BEFORE"
+				"WITH"
 				"TO")
   "Used for highlighting; Don't change without re-evaluating the
   file.")
@@ -248,6 +254,28 @@ re-evaluating `cg-kw-re' (or all of cg.el)." )
   (modify-syntax-entry ?« "." table)
                        table))
 
+(defun cg-syntax-at-pos ()
+  (let ((ppss (syntax-ppss)))
+    (cond
+     ((nth 8 ppss) (if (nth 4 ppss) 'comment 'string))
+     ((nth 1 ppss) 'paren))))
+
+(defun cg-beginning-of-defun ()
+  (re-search-backward defun-prompt-regexp nil 'noerror)
+  (while (cg-syntax-at-pos)
+    (re-search-backward defun-prompt-regexp nil 'noerror))
+  (re-search-backward "\"<[^\"]>\"" (line-beginning-position) 'noerror))
+
+(defun cg-end-of-defun ()
+  (and (search-forward ";")
+       (re-search-forward defun-prompt-regexp nil 'noerror)
+       (goto-char (match-beginning 0)))
+  (while (cg-syntax-at-pos)
+    (and (search-forward ";")
+	 (re-search-forward defun-prompt-regexp nil 'noerror)
+	 (goto-char (match-beginning 0))))
+  (re-search-backward "\"<[^\"]>\"" (line-beginning-position) 'noerror))
+
 ;;;###autoload
 (defun cg-mode ()
   "Major mode for editing Constraint Grammar files.
@@ -279,6 +307,9 @@ CG-mode provides the following specific keyboard key bindings:
   (set-syntax-table cg-mode-syntax-table)
   (set (make-local-variable 'parse-sexp-ignore-comments) t)
   (set (make-local-variable 'parse-sexp-lookup-properties) t)
+  (set (make-local-variable 'defun-prompt-regexp) cg-kw-re)
+  (set (make-local-variable 'beginning-of-defun-function) #'cg-beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function) #'cg-end-of-defun)
   (setq indent-line-function #'cg-indent-line)
   (easy-mmode-pretty-mode-name 'cg-mode " cg")
   (when font-lock-mode
@@ -286,6 +317,8 @@ CG-mode provides the following specific keyboard key bindings:
     (font-lock-set-defaults)
     (font-lock-fontify-buffer))
   (add-hook 'after-change-functions #'cg-after-change nil 'buffer-local)
+  (let ((buf (current-buffer)))
+    (run-with-idle-timer 1 'repeat 'cg-output-hl buf))
   (run-mode-hooks #'cg-mode-hook))
 
 
@@ -466,7 +499,7 @@ least -- selects the whole string \"SELECT:1022:rulename\")."
                           (yank)
                           (buffer-substring-no-properties (point-min)(point-max))))))
     (if (string-match
-         "\\(\\(select\\|iff\\|remove\\|map\\|addcohort\\|remcohort\\|copy\\|add\\|substitute\\):\\)?\\([0-9]+\\)"
+         "\\(\\(select\\|iff\\|remove\\|map\\|addcohort\\|remcohort\\|switch\\|copy\\|add\\|substitute\\):\\)?\\([0-9]+\\)"
          rule)
         (progn (goto-char (point-min))
 	       (forward-line (1- (string-to-number (match-string 3 rule))))
@@ -481,14 +514,18 @@ least -- selects the whole string \"SELECT:1022:rulename\")."
 (defvar cg--file nil
   "Which CG file the `cg-output-mode' (and `cg--check-cache-buffer')
 buffer corresponds to.")
+(make-variable-buffer-local 'cg--file)
 (defvar cg--tmp nil     ; TODO: could use cg--file iff buffer-modified-p
   "Which temporary file was sent in lieu of `cg--file' to
 compilation (in case the buffer of `cg--file' was not saved)")
+(make-variable-buffer-local 'cg--tmp)
 (defvar cg--cache-in nil
   "Which input buffer the `cg--check-cache-buffer' corresponds
 to.")
+(make-variable-buffer-local 'cg--cache-in)
 (defvar cg--cache-pre-pipe nil
   "Which pre-pipe the output of `cg--check-cache-buffer' had.")
+(make-variable-buffer-local 'cg--cache-pre-pipe)
 
 (unless (fboundp 'file-name-base)	; shim for 24.3 function
   (defun file-name-base (&optional filename)
@@ -773,20 +810,45 @@ buffer (so 0 is after each change)."
       cg-check-after-change-secs
       nil
       (lambda ()
-        (let ((proc (get-buffer-process (get-buffer-create (compilation-buffer-name
-                                                            "cg-output"
-                                                            'cg-output-mode
-                                                            'cg-output-buffer-name)))))
-          (unless (and proc (eq (process-status proc) 'run))
-            (with-demoted-errors (cg-check)))))))))
-
-
+        (unless (cg-output-running)
+	  (with-demoted-errors (cg-check))))))))
+
+(defun cg-output-hl (cg-buffer)
+  (when (eq (current-buffer) cg-buffer)
+    (let* ((sym (symbol-at-point))
+	   (sym-re (concat "[ \"]\\("
+			   (regexp-quote (symbol-name sym))
+			   "\\)\\([\" ]\\|$\\)")))
+      ;; TODO: make regexp-opts of the LIST definitions and search
+      ;; those as well?
+      (with-current-buffer (cg-output-buffer)
+	(when (and sym
+		   (get-buffer-window)
+		   (not (cg-output-running)))
+	  (remove-overlays (point-min) (point-max) 'face 'lazy-highlight)
+	  (goto-char (point-min))
+	  (while (re-search-forward sym-re nil 'noerror)
+	    (overlay-put (make-overlay (match-beginning 1) (match-end 1))
+			 'face 'lazy-highlight)))))))
+
+(defun cg-output-running ()
+  (let ((proc (get-buffer-process (cg-output-buffer))))
+    (and proc (eq (process-status proc) 'run))))
 
 (defun cg-output-buffer-name (mode)
   (if (equal mode "cg-output")
       (concat "*CG output for " (file-name-base cg--file) "*")
     (error "Unexpected mode %S" mode)))
 
+(defun cg-output-buffer ()
+  (let ((cg--file (if (eq major-mode 'cg-mode)
+		      (buffer-file-name)
+		    cg--file)))
+    (get-buffer-create (compilation-buffer-name
+			"cg-output"
+			'cg-output-mode
+			'cg-output-buffer-name))))
+
 (defun cg-end-process (proc &optional string)
   "End `proc', optionally first sending in `string'."
   (when string
@@ -878,13 +940,13 @@ Similarly, `cg-post-pipe' is run on output."
 
 (defun cg-back-to-file ()
   (interactive)
-  (bury-buffer)
-  (let* ((cg-buffer (find-buffer-visiting cg--file))
-         (cg-window (get-buffer-window cg-buffer)))
-    
-    (if cg-window
-        (select-window cg-window)
-      (pop-to-buffer cg-buffer))))
+  (let ((cg-buffer (find-buffer-visiting cg--file)))
+    (bury-buffer)
+    (let ((cg-window (get-buffer-window cg-buffer)))
+      
+      (if cg-window
+	  (select-window cg-window)
+	(pop-to-buffer cg-buffer)))))
 
 
 (defun cg-back-to-file-and-check ()
diff --git a/manual/installation.xml b/manual/installation.xml
index 6dd4aa5..b20e505 100644
--- a/manual/installation.xml
+++ b/manual/installation.xml
@@ -25,13 +25,11 @@
   <section id="ubuntu-debian">
     <title>Ubuntu / Debian</title>
     <para>
-      For any currently supported version of Ubuntu or compatible derivatives thereof (such as Linux Mint),
-      there is a <ulink url="https://launchpad.net/~tinodidriksen/+archive/cg3">PPA available from Launchpad</ulink>,
+      For any currently supported version of Debian/Ubuntu or compatible derivatives thereof (such as Linux Mint),
+      there is a <ulink url="http://apertium.projectjj.com/apt/">ready-made nightly repository</ulink>,
       easily installable via
       <screen>
-        sudo apt-get install software-properties-common
-        sudo add-apt-repository ppa:tinodidriksen/cg3
-        sudo apt-get update
+        wget http://apertium.projectjj.com/apt/install-nightly.sh -O - | sudo bash
         sudo apt-get install cg3
       </screen>
       Rest of this page can be skipped.
@@ -60,7 +58,21 @@
   </section>
 
   <section id="fedora">
-    <title>Fedora / Red Hat / CentOS</title>
+    <title>Fedora / Red Hat / CentOS / OpenSUSE</title>
+    <para>
+      For any currently supported version of these RPM-based distros or compatible derivatives thereof, there is a
+      <ulink url="https://build.opensuse.org/project/show/home:TinoDidriksen:nightly">ready-made nightly repository</ulink>,
+      installable via e.g.
+      <screen>
+        su -
+        wget 'http://download.opensuse.org/repositories/home:/TinoDidriksen:/nightly/CentOS_7/home:TinoDidriksen:nightly.repo' -O /etc/yum.repos.d/td-nightly.repo
+        yum check-upgrade
+        yum install cg3
+      </screen>
+      See <ulink url="https://en.opensuse.org/openSUSE:Build_Service_Enduser_Info">openSUSE:Build_Service_Enduser_Info</ulink>
+      for how to use on other distros.
+      Rest of this page can be skipped.
+    </para>
     <para>
       Steps tested on a clean install of CentOS 6.3, but should work on any version.
       It is assumed you have a working network connection.
diff --git a/scripts/profile-revisions.php b/scripts/profile-revisions.php
index 3305614..c9f7395 100755
--- a/scripts/profile-revisions.php
+++ b/scripts/profile-revisions.php
@@ -14,13 +14,13 @@ function profile_revision($rev) {
 
 	if (file_exists('./src/all_vislcg3.cpp')) {
 		echo "Using all_vislcg3.cpp and Boost...\n";
-		echo shell_exec('g++ -std=c++11 -DHAVE_BOOST -DNDEBUG -pipe -Wall -Wextra -Wno-deprecated -fPIC -O3 -L/usr/local/lib64 -L/usr/local/lib -licuio -licuuc -Iinclude -Iinclude/exec-stream ./src/all_vislcg3.cpp -o vislcg3 2>&1');
-		echo shell_exec('g++ -std=c++11 -DHAVE_BOOST -DNDEBUG -pipe -Wall -Wextra -Wno-deprecated -fPIC -O3 -L/usr/local/lib64 -L/usr/local/lib -licuio -licuuc -ltcmalloc -Iinclude -Iinclude/exec-stream ./src/all_vislcg3.cpp -o vislcg3-tc 2>&1');
+		echo shell_exec('g++ -std=c++11 -DHAVE_BOOST -DNDEBUG -pthread -pipe -Wall -Wextra -Wno-deprecated -fPIC -O3 -Iinclude -Iinclude/exec-stream ./src/all_vislcg3.cpp -o vislcg3 -L/usr/lib/x86_64-linux-gnu -licui18n -licudata -licuio -licuuc 2>&1');
+		echo shell_exec('g++ -std=c++11 -DHAVE_BOOST -DNDEBUG -pthread -pipe -Wall -Wextra -Wno-deprecated -fPIC -O3 -Iinclude -Iinclude/exec-stream ./src/all_vislcg3.cpp -o vislcg3-tc -L/usr/lib/x86_64-linux-gnu -licui18n -licudata -licuio -licuuc -ltcmalloc 2>&1');
 	}
 	else {
 		echo "Using old-style without Boost...\n";
-		echo shell_exec('g++ -std=c++11 -DHAVE_BOOST -pipe -Wall -Wextra -Wno-deprecated -fPIC -O3 -L/usr/local/lib64 -L/usr/local/lib -licuio -licuuc -Iinclude -Iinclude/exec-stream $(ls -1 ./src/*.cpp | egrep -v "/test_" | egrep -v "/cg_" | egrep -v "/all_" | grep -v Apertium | grep -v Matxin | grep -v FormatConverter) -o vislcg3 2>&1');
-		echo shell_exec('g++ -std=c++11 -DHAVE_BOOST -pipe -Wall -Wextra -Wno-deprecated -fPIC -O3 -L/usr/local/lib64 -L/usr/local/lib -licuio -licuuc -ltcmalloc -Iinclude -Iinclude/exec-stream $(ls -1 ./src/*.cpp | egrep -v "/test_" | egrep -v "/cg_" | egrep -v "/all_" | grep -v Apertium | grep -v Matxin | grep -v FormatConverter) -o vislcg3-tc 2>&1');
+		echo shell_exec('g++ -std=c++11 -DHAVE_BOOST -pthread -pipe -Wall -Wextra -Wno-deprecated -fPIC -O3 -Iinclude -Iinclude/exec-stream $(ls -1 ./src/*.cpp | egrep -v "/test_" | egrep -v "/cg_" | egrep -v "/all_" | grep -v Apertium | grep -v Matxin | grep -v FormatConverter) -o vislcg3 -L/usr/lib/x86_64-linux-gnu -licui18n -licudata -licuio -licuuc -ltcmalloc 2>&1');
+		echo shell_exec('g++ -std=c++11 -DHAVE_BOOST -pthread -pipe -Wall -Wextra -Wno-deprecated -fPIC -O3 -ltcmalloc -Iinclude -Iinclude/exec-stream $(ls -1 ./src/*.cpp | egrep -v "/test_" | egrep -v "/cg_" | egrep -v "/all_" | grep -v Apertium | grep -v Matxin | grep -v FormatConverter) -o vislcg3-tc -L/usr/lib/x86_64-linux-gnu -licui18n -licudata -licuio -licuuc -ltcmalloc 2>&1');
 	}
 
 	if (!file_exists('vislcg3') || !file_exists('vislcg3-tc')) {
@@ -73,8 +73,8 @@ function profile_revision($rev) {
 	shell_exec('rm -rf '.$dir.' 2>&1 >/dev/null');
 }
 
-$revs = array(10016, 9645, 9274, 9249, 8923, 8001, 7397, 7134, 7000, 6987, 6898, 6885, 6781, 6692, 6500, 6328, 6268, 6242, 6170, 5932, 5930, 5926, 5918, 5839, 5810, 5773, 5729, 5431, 5129, 5042, 4879, 4779, 4545, 4513, 4493, 4474, 4410, 4292, 4031, 3991, 3896, 3852, 3800, 3689, 3682, 3617);
-$revs = array(10034);
+$revs = array(10297, 10034, 10016, 9645, 9274, 9249, 8923, 8001, 7397, 7134, 7000, 6987, 6898, 6885, 6781, 6692, 6500, 6328, 6268, 6242, 6170, 5932, 5930, 5926, 5918, 5839, 5810, 5773, 5729, 5431, 5129, 5042, 4879, 4779, 4545, 4513, 4493, 4474, 4410, 4292, 4031, 3991, 3896, 3852, 3800, 3689, 3682, 3617);
+$revs = array(10373);
 foreach ($revs as $rev) {
 	profile_revision($rev);
 }
diff --git a/src/ApertiumApplicator.cpp b/src/ApertiumApplicator.cpp
index 8b8f875..47470ce 100644
--- a/src/ApertiumApplicator.cpp
+++ b/src/ApertiumApplicator.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -214,7 +214,7 @@ void ApertiumApplicator::runGrammarOnText(istream& input, UFILE *output) {
 			if (cCohort && cCohort->readings.empty()) {
 				initEmptyCohort(*cCohort);
 			}
-			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->hash)) {
+			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->number)) {
 			  // ie. we've read some cohorts
 				foreach (ReadingList, cCohort->readings, iter, iter_end) {
 					addTagToReading(**iter, endtag);
@@ -226,7 +226,7 @@ void ApertiumApplicator::runGrammarOnText(istream& input, UFILE *output) {
 				cCohort = 0;
 				numCohorts++;
 			} // end >= soft_limit
-			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->hash)))) {
+			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->number)))) {
 				if (cSWindow->cohorts.size() >= hard_limit) {
 					u_fprintf(ux_stderr, "Warning: Hard limit of %u cohorts reached at line %u - forcing break.\n", hard_limit, numLines);
 					u_fflush(ux_stderr);
diff --git a/src/ApertiumApplicator.hpp b/src/ApertiumApplicator.hpp
index d3586db..536da8c 100644
--- a/src/ApertiumApplicator.hpp
+++ b/src/ApertiumApplicator.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/BinaryGrammar.cpp b/src/BinaryGrammar.cpp
index 0afb108..2675fd4 100644
--- a/src/BinaryGrammar.cpp
+++ b/src/BinaryGrammar.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -29,12 +29,14 @@ BinaryGrammar::BinaryGrammar(Grammar& res, UFILE *ux_err) {
 	ux_stderr = ux_err;
 	result = &res;
 	grammar = result;
+	verbosity = 0;
 }
 
 void BinaryGrammar::setCompatible(bool) {
 }
 
-void BinaryGrammar::setVerbosity(uint32_t) {
+void BinaryGrammar::setVerbosity(uint32_t v) {
+	verbosity = v;
 }
 
 int BinaryGrammar::parse_grammar_from_file(const char *filename, const char *, const char *) {
diff --git a/src/BinaryGrammar.hpp b/src/BinaryGrammar.hpp
index 9b8cf17..7a55bbb 100644
--- a/src/BinaryGrammar.hpp
+++ b/src/BinaryGrammar.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -45,6 +45,11 @@ namespace CG3 {
 
 		typedef stdext::hash_map<ContextualTest*,uint32_t> deferred_t;
 		deferred_t deferred_tmpls;
+
+		uint32FlatHashSet seen_uint32;
+
+		int readBinaryGrammar_10043(FILE *input);
+		ContextualTest *readContextualTest_10043(FILE *input);
 	};
 }
 
diff --git a/src/BinaryGrammar_read.cpp b/src/BinaryGrammar_read.cpp
index ad776a3..7e4ad71 100644
--- a/src/BinaryGrammar_read.cpp
+++ b/src/BinaryGrammar_read.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -76,6 +76,14 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 
 	fread(&u32tmp, sizeof(uint32_t), 1, input);
 	u32tmp = (uint32_t)ntohl(u32tmp);
+	if (u32tmp <= 10297) {
+		if (verbosity >= 1) {
+			u_fprintf(ux_stderr, "Warning: Grammar revision is %u, but current format is %u or later. Please recompile the binary grammar with latest CG-3.\n", u32tmp, CG3_FEATURE_REV);
+			u_fflush(ux_stderr);
+		}
+		fseek(input, 0, SEEK_SET);
+		return readBinaryGrammar_10043(input);
+	}
 	if (u32tmp < CG3_TOO_OLD) {
 		u_fprintf(ux_stderr, "Error: Grammar revision is %u, but this loader requires %u or later!\n", u32tmp, CG3_TOO_OLD);
 		CG3Quit(1);
@@ -285,10 +293,7 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 			fread(&u32tmp, sizeof(uint32_t), 1, input);
 			s->number = (uint32_t)ntohl(u32tmp);
 		}
-		if (fields & (1 << 1)) {
-			fread(&u32tmp, sizeof(uint32_t), 1, input);
-			s->hash = (uint32_t)ntohl(u32tmp);
-		}
+		// Field 1 is unused
 		if (fields & (1 << 2)) {
 			fread(&u8tmp, sizeof(uint8_t), 1, input);
 			s->type = u8tmp;
@@ -336,7 +341,6 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 				s->setName(&gbuffers[0][0]);
 			}
 		}
-		grammar->sets_by_contents[s->hash] = s;
 		grammar->sets_list[s->number] = s;
 	}
 
@@ -352,13 +356,13 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 	if (fields & (1 << 9)) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
 		u32tmp = (uint32_t)ntohl(u32tmp);
-		grammar->delimiters = grammar->sets_by_contents.find(u32tmp)->second;
+		grammar->delimiters = grammar->sets_list[u32tmp];
 	}
 
 	if (fields & (1 << 10)) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
 		u32tmp = (uint32_t)ntohl(u32tmp);
-		grammar->soft_delimiters = grammar->sets_by_contents.find(u32tmp)->second;
+		grammar->soft_delimiters = grammar->sets_list[u32tmp];
 	}
 
 	u32tmp = 0;
@@ -367,15 +371,9 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 		u32tmp = (uint32_t)ntohl(u32tmp);
 	}
 	uint32_t num_contexts = u32tmp;
-	grammar->contexts_list.resize(num_contexts);
 	for (uint32_t i = 0; i < num_contexts; i++) {
 		ContextualTest *t = readContextualTest(input);
-		t->number = i + 1;
-		grammar->contexts_list[i] = t;
-		if (t->name) {
-			grammar->templates[t->name] = t;
-			grammar->template_list.push_back(t);
-		}
+		grammar->contexts[t->hash] = t;
 	}
 
 	u32tmp = 0;
@@ -469,7 +467,7 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
 		u32tmp = (uint32_t)ntohl(u32tmp);
 		if (u32tmp) {
-			r->dep_target = grammar->contexts_list[u32tmp-1];
+			r->dep_target = grammar->contexts[u32tmp];
 		}
 
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
@@ -478,7 +476,7 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 		for (uint32_t j=0 ; j<num_dep_tests ; j++) {
 			fread(&u32tmp, sizeof(uint32_t), 1, input);
 			u32tmp = (uint32_t)ntohl(u32tmp);
-			ContextualTest *t = grammar->contexts_list[u32tmp - 1];
+			ContextualTest *t = grammar->contexts[u32tmp];
 			r->addContextualTest(t, r->dep_tests);
 		}
 
@@ -488,15 +486,15 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 		for (uint32_t j=0 ; j<num_tests ; j++) {
 			fread(&u32tmp, sizeof(uint32_t), 1, input);
 			u32tmp = (uint32_t)ntohl(u32tmp);
-			ContextualTest *t = grammar->contexts_list[u32tmp - 1];
+			ContextualTest *t = grammar->contexts[u32tmp];
 			r->addContextualTest(t, r->tests);
 		}
 		grammar->rule_by_number[r->number] = r;
 	}
 
-	// Bind the named templates to where they are used
+	// Bind the templates to where they are used
 	foreach (deferred_t, deferred_tmpls, it, it_end) {
-		it->first->tmpl = grammar->templates.find(it->second)->second;
+		it->first->tmpl = grammar->contexts.find(it->second)->second;
 	}
 
 	ucnv_close(conv);
@@ -532,7 +530,7 @@ ContextualTest *BinaryGrammar::readContextualTest(FILE *input) {
 	if (fields & (1 << 3)) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
 		tmpl = (uint32_t)ntohl(u32tmp);
-		t->tmpl = reinterpret_cast<ContextualTest*>(u32tmp);
+		deferred_tmpls[t] = tmpl;
 	}
 	if (fields & (1 << 4)) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
@@ -558,29 +556,22 @@ ContextualTest *BinaryGrammar::readContextualTest(FILE *input) {
 		fread(&i32tmp, sizeof(int32_t), 1, input);
 		t->offset_sub = (int32_t)ntohl(i32tmp);
 	}
-	if (fields & (1 << 12)) {
-		fread(&i32tmp, sizeof(int32_t), 1, input);
-		t->name = (int32_t)ntohl(i32tmp);
-	}
 	if (fields & (1 << 10)) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
 		uint32_t num_ors = (uint32_t)ntohl(u32tmp);
 		for (uint32_t i=0 ; i<num_ors ; ++i) {
 			fread(&u32tmp, sizeof(uint32_t), 1, input);
 			u32tmp = (uint32_t)ntohl(u32tmp);
-			ContextualTest *to = grammar->contexts_list[u32tmp-1];
+			ContextualTest *to = grammar->contexts[u32tmp];
 			t->ors.push_back(to);
 		}
 	}
 	if (fields & (1 << 11)) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
 		u32tmp = (uint32_t)ntohl(u32tmp);
-		t->linked = grammar->contexts_list[u32tmp - 1];
+		t->linked = grammar->contexts[u32tmp];
 	}
 
-	if (tmpl) {
-		deferred_tmpls[t] = tmpl;
-	}
 	return t;
 }
 
diff --git a/src/BinaryGrammar_read.cpp b/src/BinaryGrammar_read_10043.cpp
similarity index 94%
copy from src/BinaryGrammar_read.cpp
copy to src/BinaryGrammar_read_10043.cpp
index ad776a3..8279771 100644
--- a/src/BinaryGrammar_read.cpp
+++ b/src/BinaryGrammar_read_10043.cpp
@@ -49,7 +49,10 @@ inline void trie_unserialize(trie_t& trie, FILE *input, Grammar& grammar, uint32
 	}
 }
 
-int BinaryGrammar::readBinaryGrammar(FILE *input) {
+static std::vector<ContextualTest*> contexts_list;
+static Grammar::contexts_t templates;
+
+int BinaryGrammar::readBinaryGrammar_10043(FILE *input) {
 	if (!input) {
 		u_fprintf(ux_stderr, "Error: Input is null - cannot read from nothing!\n");
 		CG3Quit(1);
@@ -76,12 +79,8 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 
 	fread(&u32tmp, sizeof(uint32_t), 1, input);
 	u32tmp = (uint32_t)ntohl(u32tmp);
-	if (u32tmp < CG3_TOO_OLD) {
-		u_fprintf(ux_stderr, "Error: Grammar revision is %u, but this loader requires %u or later!\n", u32tmp, CG3_TOO_OLD);
-		CG3Quit(1);
-	}
-	if (u32tmp > CG3_FEATURE_REV) {
-		u_fprintf(ux_stderr, "Error: Grammar revision is %u, but this loader only knows up to revision %u!\n", u32tmp, CG3_FEATURE_REV);
+	if (u32tmp < 10043) {
+		u_fprintf(ux_stderr, "Error: Grammar revision is %u, but this loader requires %u or later!\n", u32tmp, 10043);
 		CG3Quit(1);
 	}
 
@@ -367,15 +366,11 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 		u32tmp = (uint32_t)ntohl(u32tmp);
 	}
 	uint32_t num_contexts = u32tmp;
-	grammar->contexts_list.resize(num_contexts);
+	contexts_list.resize(num_contexts);
 	for (uint32_t i = 0; i < num_contexts; i++) {
-		ContextualTest *t = readContextualTest(input);
-		t->number = i + 1;
-		grammar->contexts_list[i] = t;
-		if (t->name) {
-			grammar->templates[t->name] = t;
-			grammar->template_list.push_back(t);
-		}
+		ContextualTest *t = readContextualTest_10043(input);
+		grammar->contexts[t->hash] = t;
+		contexts_list[i] = t;
 	}
 
 	u32tmp = 0;
@@ -469,7 +464,7 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
 		u32tmp = (uint32_t)ntohl(u32tmp);
 		if (u32tmp) {
-			r->dep_target = grammar->contexts_list[u32tmp-1];
+			r->dep_target = contexts_list[u32tmp-1];
 		}
 
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
@@ -478,7 +473,7 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 		for (uint32_t j=0 ; j<num_dep_tests ; j++) {
 			fread(&u32tmp, sizeof(uint32_t), 1, input);
 			u32tmp = (uint32_t)ntohl(u32tmp);
-			ContextualTest *t = grammar->contexts_list[u32tmp - 1];
+			ContextualTest *t = contexts_list[u32tmp - 1];
 			r->addContextualTest(t, r->dep_tests);
 		}
 
@@ -488,7 +483,7 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 		for (uint32_t j=0 ; j<num_tests ; j++) {
 			fread(&u32tmp, sizeof(uint32_t), 1, input);
 			u32tmp = (uint32_t)ntohl(u32tmp);
-			ContextualTest *t = grammar->contexts_list[u32tmp - 1];
+			ContextualTest *t = contexts_list[u32tmp - 1];
 			r->addContextualTest(t, r->tests);
 		}
 		grammar->rule_by_number[r->number] = r;
@@ -496,14 +491,18 @@ int BinaryGrammar::readBinaryGrammar(FILE *input) {
 
 	// Bind the named templates to where they are used
 	foreach (deferred_t, deferred_tmpls, it, it_end) {
-		it->first->tmpl = grammar->templates.find(it->second)->second;
+		BOOST_AUTO(tmt, templates.find(it->second));
+		it->first->tmpl = tmt->second;
 	}
 
 	ucnv_close(conv);
+	// Create the dummy set
+	grammar->allocateDummySet();
+	grammar->is_binary = false;
 	return 0;
 }
 
-ContextualTest *BinaryGrammar::readContextualTest(FILE *input) {
+ContextualTest *BinaryGrammar::readContextualTest_10043(FILE *input) {
 	ContextualTest *t = grammar->allocateContextualTest();
 	uint32_t fields = 0;
 	uint32_t u32tmp = 0;
@@ -559,8 +558,8 @@ ContextualTest *BinaryGrammar::readContextualTest(FILE *input) {
 		t->offset_sub = (int32_t)ntohl(i32tmp);
 	}
 	if (fields & (1 << 12)) {
-		fread(&i32tmp, sizeof(int32_t), 1, input);
-		t->name = (int32_t)ntohl(i32tmp);
+		fread(&u32tmp, sizeof(uint32_t), 1, input);
+		templates[(uint32_t)ntohl(u32tmp)] = t;
 	}
 	if (fields & (1 << 10)) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
@@ -568,14 +567,14 @@ ContextualTest *BinaryGrammar::readContextualTest(FILE *input) {
 		for (uint32_t i=0 ; i<num_ors ; ++i) {
 			fread(&u32tmp, sizeof(uint32_t), 1, input);
 			u32tmp = (uint32_t)ntohl(u32tmp);
-			ContextualTest *to = grammar->contexts_list[u32tmp-1];
+			ContextualTest *to = contexts_list[u32tmp-1];
 			t->ors.push_back(to);
 		}
 	}
 	if (fields & (1 << 11)) {
 		fread(&u32tmp, sizeof(uint32_t), 1, input);
 		u32tmp = (uint32_t)ntohl(u32tmp);
-		t->linked = grammar->contexts_list[u32tmp - 1];
+		t->linked = contexts_list[u32tmp - 1];
 	}
 
 	if (tmpl) {
diff --git a/src/BinaryGrammar_write.cpp b/src/BinaryGrammar_write.cpp
index 3c8601f..d2dfcdf 100644
--- a/src/BinaryGrammar_write.cpp
+++ b/src/BinaryGrammar_write.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -84,7 +84,7 @@ int BinaryGrammar::writeBinaryGrammar(FILE *output) {
 	if (grammar->soft_delimiters) {
 		fields |= (1 << 10);
 	}
-	if (!grammar->contexts_list.empty()) {
+	if (!grammar->contexts.empty()) {
 		fields |= (1 << 11);
 	}
 	if (!grammar->rule_by_number.empty()) {
@@ -206,10 +206,10 @@ int BinaryGrammar::writeBinaryGrammar(FILE *output) {
 		u32tmp = (uint32_t)htonl((uint32_t)grammar->parentheses.size());
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 	}
-	const_foreach (uint32Map, grammar->parentheses, iter_par, iter_par_end) {
-		u32tmp = (uint32_t)htonl((uint32_t)iter_par->first);
+	boost_foreach (const Grammar::parentheses_t::value_type& iter_par, grammar->parentheses) {
+		u32tmp = (uint32_t)htonl(iter_par.first);
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
-		u32tmp = (uint32_t)htonl((uint32_t)iter_par->second);
+		u32tmp = (uint32_t)htonl(iter_par.second);
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 	}
 
@@ -240,10 +240,7 @@ int BinaryGrammar::writeBinaryGrammar(FILE *output) {
 			fields |= (1 << 0);
 			writeSwapped(buffer, s->number);
 		}
-		if (s->hash) {
-			fields |= (1 << 1);
-			writeSwapped(buffer, s->hash);
-		}
+		// Field 1 is unused
 		if (s->type) {
 			fields |= (1 << 2);
 			writeSwapped(buffer, s->type);
@@ -283,21 +280,22 @@ int BinaryGrammar::writeBinaryGrammar(FILE *output) {
 	}
 
 	if (grammar->delimiters) {
-		u32tmp = (uint32_t)htonl((uint32_t)grammar->delimiters->hash);
+		u32tmp = (uint32_t)htonl((uint32_t)grammar->delimiters->number);
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 	}
 
 	if (grammar->soft_delimiters) {
-		u32tmp = (uint32_t)htonl((uint32_t)grammar->soft_delimiters->hash);
+		u32tmp = (uint32_t)htonl((uint32_t)grammar->soft_delimiters->number);
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 	}
 
-	if (!grammar->contexts_list.empty()) {
-		u32tmp = (uint32_t)htonl((uint32_t)grammar->contexts_list.size());
+	seen_uint32.clear();
+	if (!grammar->contexts.empty()) {
+		u32tmp = (uint32_t)htonl((uint32_t)grammar->contexts.size());
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 	}
-	const_foreach (ContextVector, grammar->contexts_list, it, it_end) {
-		writeContextualTest(*it, output);
+	for (BOOST_AUTO(cntx, grammar->contexts.begin()); cntx != grammar->contexts.end(); ++cntx) {
+		writeContextualTest(cntx->second, output);
 	}
 
 	if (!grammar->rule_by_number.empty()) {
@@ -385,7 +383,7 @@ int BinaryGrammar::writeBinaryGrammar(FILE *output) {
 
 		u32tmp = 0;
 		if (r->dep_target) {
-			u32tmp = (uint32_t)htonl(r->dep_target->number);
+			u32tmp = (uint32_t)htonl(r->dep_target->hash);
 		}
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 
@@ -393,14 +391,14 @@ int BinaryGrammar::writeBinaryGrammar(FILE *output) {
 		u32tmp = (uint32_t)htonl(r->dep_tests.size());
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 		const_foreach (ContextList, r->dep_tests, it, it_end) {
-			u32tmp = (uint32_t)htonl((*it)->number);
+			u32tmp = (uint32_t)htonl((*it)->hash);
 			fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 		}
 
 		u32tmp = (uint32_t)htonl(r->tests.size());
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 		const_foreach (ContextList, r->tests, it, it_end) {
-			u32tmp = (uint32_t)htonl((*it)->number);
+			u32tmp = (uint32_t)htonl((*it)->hash);
 			fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 		}
 	}
@@ -410,6 +408,21 @@ int BinaryGrammar::writeBinaryGrammar(FILE *output) {
 }
 
 void BinaryGrammar::writeContextualTest(ContextualTest *t, FILE *output) {
+	if (seen_uint32.count(t->hash)) {
+		return;
+	}
+	seen_uint32.insert(t->hash);
+
+	if (t->tmpl) {
+		writeContextualTest(t->tmpl, output);
+	}
+	const_foreach(ContextList, t->ors, iter, iter_end) {
+		writeContextualTest(*iter, output);
+	}
+	if (t->linked) {
+		writeContextualTest(t->linked, output);
+	}
+
 	std::ostringstream buffer;
 	uint32_t fields = 0;
 	uint32_t u32tmp = 0;
@@ -435,7 +448,7 @@ void BinaryGrammar::writeContextualTest(ContextualTest *t, FILE *output) {
 	}
 	if (t->tmpl) {
 		fields |= (1 << 3);
-		writeSwapped(buffer, t->tmpl->name);
+		writeSwapped(buffer, t->tmpl->hash);
 	}
 	if (t->target) {
 		fields |= (1 << 4);
@@ -467,10 +480,6 @@ void BinaryGrammar::writeContextualTest(ContextualTest *t, FILE *output) {
 	if (t->linked) {
 		fields |= (1 << 11);
 	}
-	if (t->name) {
-		fields |= (1 << 12);
-		writeSwapped(buffer, t->name);
-	}
 
 	u32tmp = (uint32_t)htonl(fields);
 	fwrite(&u32tmp, sizeof(uint32_t), 1, output);
@@ -481,13 +490,13 @@ void BinaryGrammar::writeContextualTest(ContextualTest *t, FILE *output) {
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 
 		const_foreach (ContextList, t->ors, iter, iter_end) {
-			u32tmp = (uint32_t)htonl((*iter)->number);
+			u32tmp = (uint32_t)htonl((*iter)->hash);
 			fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 		}
 	}
 
 	if (t->linked) {
-		u32tmp = (uint32_t)htonl(t->linked->number);
+		u32tmp = (uint32_t)htonl(t->linked->hash);
 		fwrite(&u32tmp, sizeof(uint32_t), 1, output);
 	}
 }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bb6c1de..1c36624 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,8 @@
 # Threading, for exec-stream
-find_package(Threads REQUIRED)
+# There's some weird bug/interaction with recent Apple toolchains and this, so disable for now.
+if(NOT APPLE)
+	find_package(Threads REQUIRED)
+endif()
 
 # Boost
 find_path(Boost_LOCAL NAMES boost/config.hpp PATHS "${CMAKE_CURRENT_SOURCE_DIR}/../include" NO_DEFAULT_PATH)
@@ -85,6 +88,7 @@ set(LIBCG3_HEADERS
 set(LIBCG3_SOURCES
 	BinaryGrammar.cpp
 	BinaryGrammar_read.cpp
+	BinaryGrammar_read_10043.cpp
 	BinaryGrammar_write.cpp
 	Cohort.cpp
 	CohortIterator.cpp
@@ -177,10 +181,11 @@ target_link_libraries(test_libcg3 ${LINKLIB})
 
 if(APPLE)
 	foreach(t cg-conv cg-comp cg-proc vislcg3)
-		get_property("_file_${t}" TARGET ${t} PROPERTY LOCATION)
+		set("_file_${t}" $<TARGET_FILE:${t}>)
 		add_custom_command(
 			TARGET ${t}
 			POST_BUILD
+			COMMAND install_name_tool -change libcg3.0.dylib @rpath/libcg3.0.dylib ${_file_${t}}
 			COMMAND install_name_tool -add_rpath @executable_path/ ${_file_${t}}
 			COMMAND install_name_tool -add_rpath @executable_path/../${CG_LIBDIR} ${_file_${t}}
 			COMMAND install_name_tool -add_rpath @loader_path/../${CG_LIBDIR} ${_file_${t}}
diff --git a/src/Cohort.cpp b/src/Cohort.cpp
index 04109d6..eac90ff 100644
--- a/src/Cohort.cpp
+++ b/src/Cohort.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Cohort.hpp b/src/Cohort.hpp
index 9c6025e..3f3fb04 100644
--- a/src/Cohort.hpp
+++ b/src/Cohort.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/CohortIterator.cpp b/src/CohortIterator.cpp
index be54388..60f8a84 100644
--- a/src/CohortIterator.cpp
+++ b/src/CohortIterator.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/CohortIterator.hpp b/src/CohortIterator.hpp
index 6e8ea78..3272ac4 100644
--- a/src/CohortIterator.hpp
+++ b/src/CohortIterator.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/ContextualTest.cpp b/src/ContextualTest.cpp
index f5fa5b6..55972ef 100644
--- a/src/ContextualTest.cpp
+++ b/src/ContextualTest.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -30,10 +30,8 @@ is_used(false),
 offset(0),
 offset_sub(0),
 line(0),
-name(0),
 hash(0),
 seed(0),
-number(0),
 pos(0),
 target(0),
 relation(0),
diff --git a/src/ContextualTest.hpp b/src/ContextualTest.hpp
index 3573afe..046a66a 100644
--- a/src/ContextualTest.hpp
+++ b/src/ContextualTest.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -93,10 +93,8 @@ namespace CG3 {
 		int32_t offset;
 		int32_t offset_sub;
 		uint32_t line;
-		uint32_t name;
 		uint32_t hash;
 		uint32_t seed;
-		uint32_t number;
 		uint64_t pos;
 		uint32_t target;
 		uint32_t relation;
diff --git a/src/FSTApplicator.cpp b/src/FSTApplicator.cpp
index 4482408..8ee522f 100644
--- a/src/FSTApplicator.cpp
+++ b/src/FSTApplicator.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -244,7 +244,7 @@ istext:
 			if (cSWindow && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && !did_soft_lookback) {
 				did_soft_lookback = true;
 				reverse_foreach (CohortVector, cSWindow->cohorts, iter, iter_end) {
-					if (doesSetMatchCohortNormal(**iter, grammar->soft_delimiters->hash)) {
+					if (doesSetMatchCohortNormal(**iter, grammar->soft_delimiters->number)) {
 						did_soft_lookback = false;
 						Cohort *cohort = delimitAt(*cSWindow, *iter);
 						cSWindow = cohort->parent->next;
@@ -259,7 +259,7 @@ istext:
 					}
 				}
 			}
-			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->hash)) {
+			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->number)) {
 				if (verbosity_level > 0) {
 					u_fprintf(ux_stderr, "Warning: Soft limit of %u cohorts reached at line %u but found suitable soft delimiter.\n", soft_limit, numLines);
 					u_fflush(ux_stderr);
@@ -274,7 +274,7 @@ istext:
 				cSWindow = 0;
 				did_soft_lookback = false;
 			}
-			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (!dep_delimit && grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->hash)))) {
+			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (!dep_delimit && grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->number)))) {
 				if (cSWindow->cohorts.size() >= hard_limit) {
 					u_fprintf(ux_stderr, "Warning: Hard limit of %u cohorts reached at line %u - forcing break.\n", hard_limit, numLines);
 					u_fflush(ux_stderr);
diff --git a/src/FSTApplicator.hpp b/src/FSTApplicator.hpp
index 3fb6ece..b997f8d 100644
--- a/src/FSTApplicator.hpp
+++ b/src/FSTApplicator.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/FormatConverter.cpp b/src/FormatConverter.cpp
index 486a3e9..5017bda 100644
--- a/src/FormatConverter.cpp
+++ b/src/FormatConverter.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/FormatConverter.hpp b/src/FormatConverter.hpp
index 0f7e478..85d637e 100644
--- a/src/FormatConverter.hpp
+++ b/src/FormatConverter.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Grammar.cpp b/src/Grammar.cpp
index e5a6efb..908b7d7 100644
--- a/src/Grammar.cpp
+++ b/src/Grammar.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -67,8 +67,8 @@ Grammar::~Grammar() {
 		delete *iter_rules;
 	}
 
-	foreach (ContextVector, contexts_list, it, it_end) {
-		delete *it;
+	for (BOOST_AUTO(cntx, contexts.begin()); cntx != contexts.end(); ++cntx) {
+		delete cntx->second;
 	}
 }
 
@@ -349,6 +349,17 @@ Set *Grammar::parseSet(const UChar *name) {
 	return tmp;
 }
 
+void Grammar::allocateDummySet() {
+	Set *set_c = allocateSet();
+	set_c->line = 0;
+	set_c->setName(stringbits[S_IGNORE].getTerminatedBuffer());
+	Tag *t = allocateTag(stringbits[S_IGNORE].getTerminatedBuffer());
+	addTagToSet(t, set_c);
+	addSet(set_c);
+	set_c->number = std::numeric_limits<uint32_t>::max();
+	sets_list.insert(sets_list.begin(), set_c);
+}
+
 Rule *Grammar::allocateRule() {
 	return new Rule;
 }
@@ -367,6 +378,10 @@ Tag *Grammar::allocateTag() {
 }
 
 Tag *Grammar::allocateTag(const UChar *txt, bool raw) {
+	if (txt[0] == 0) {
+		u_fprintf(ux_stderr, "Error: Empty tag on line %u! Forgot to fill in a ()?\n", lines);
+		CG3Quit(1);
+	}
 	if (txt[0] == '(') {
 		u_fprintf(ux_stderr, "Error: Tag '%S' cannot start with ( on line %u! Possible extra opening ( or missing closing ) to the left. If you really meant it, escape it as \\(.\n", txt, lines);
 		CG3Quit(1);
@@ -457,8 +472,6 @@ ContextualTest *Grammar::addContextualTest(ContextualTest *t) {
 			contexts[t->hash+seed] = t;
 			t->hash += seed;
 			t->seed = seed;
-			contexts_list.push_back(t);
-			t->number = contexts_list.size();
 			if (verbosity_level > 1 && seed) {
 				u_fprintf(ux_stderr, "Warning: Context on line %u got hash seed %u.\n", t->line, seed);
 				u_fflush(ux_stderr);
@@ -484,7 +497,6 @@ void Grammar::addTemplate(ContextualTest *test, const UChar *name) {
 		CG3Quit(1);
 	}
 	templates[cn] = test;
-	template_list.push_back(test);
 }
 
 void Grammar::addAnchor(const UChar *to, uint32_t at, bool primary) {
@@ -521,7 +533,13 @@ void Grammar::renameAllRules() {
 
 void Grammar::reindex(bool unused_sets) {
 	foreach (Setuint32HashMap, sets_by_contents, dset, dset_end) {
-		dset->second->type &= ~ST_USED;
+		if (dset->second->number == std::numeric_limits<uint32_t>::max()) {
+			dset->second->type |= ST_USED;
+			continue;
+		}
+		if (!(dset->second->type & ST_STATIC)) {
+			dset->second->type &= ~ST_USED;
+		}
 		dset->second->number = 0;
 	}
 
@@ -552,43 +570,14 @@ void Grammar::reindex(bool unused_sets) {
 	after_sections.clear();
 	null_section.clear();
 	sections.clear();
-	sets_list.clear();
+	if (!is_binary) {
+		sets_list.resize(1);
+		sets_list[0]->number = 0;
+	}
 	set_name_seeds.clear();
 	sets_any = 0;
 	rules_any = 0;
 
-	foreach (Setuint32HashMap, sets_by_contents, dset, dset_end) {
-		Set *to = dset->second;
-		if (to->type & ST_STATIC) {
-			uint32_t nhash = hash_value(to->name);
-			const uint32_t chash = to->hash;
-
-			if (sets_by_name.find(nhash) == sets_by_name.end()) {
-				sets_by_name[nhash] = chash;
-			}
-			else if (chash != sets_by_contents.find(sets_by_name.find(nhash)->second)->second->hash) {
-				Set *a = sets_by_contents.find(sets_by_name.find(nhash)->second)->second;
-				if (a->name == to->name) {
-					u_fprintf(ux_stderr, "Error: Static set %S already defined. Redefinition attempted!\n", a->name.c_str());
-					CG3Quit(1);
-				}
-				else {
-					for (uint32_t seed=0 ; seed<1000 ; ++seed) {
-						if (sets_by_name.find(nhash+seed) == sets_by_name.end()) {
-							if (verbosity_level > 0) {
-								u_fprintf(ux_stderr, "Warning: Static set %S got hash seed %u.\n", to->name.c_str(), seed);
-								u_fflush(ux_stderr);
-							}
-							set_name_seeds[to->name] = seed;
-							sets_by_name[nhash+seed] = chash;
-							break;
-						}
-					}
-				}
-			}
-		}
-	}
-
 	foreach (TagVector, single_tags_list, iter, iter_end) {
 		if ((*iter)->regexp && (*iter)->tag[0] == '/') {
 			regex_tags.insert((*iter)->regexp);
@@ -596,6 +585,9 @@ void Grammar::reindex(bool unused_sets) {
 		if (((*iter)->type & T_CASE_INSENSITIVE) && (*iter)->tag[0] == '/') {
 			icase_tags.insert((*iter));
 		}
+		if (is_binary) {
+			continue;
+		}
 		if (!(*iter)->vs_sets) {
 			continue;
 		}
@@ -629,14 +621,13 @@ void Grammar::reindex(bool unused_sets) {
 		}
 	}
 
-#ifdef TR_RATIO
-	boost::unordered_map<std::pair<uint32_t, uint32_t>, size_t> unique_targets;
-	size_t max_target = 0;
-#endif
 	foreach (RuleVector, rule_by_number, iter_rule, iter_rule_end) {
 		if ((*iter_rule)->wordform) {
 			wf_rules.push_back(*iter_rule);
 		}
+		if (is_binary) {
+			continue;
+		}
 		Set *s = 0;
 		s = getSet((*iter_rule)->target);
 		s->markUsed(*this);
@@ -663,36 +654,25 @@ void Grammar::reindex(bool unused_sets) {
 		foreach (ContextList, (*iter_rule)->dep_tests, it, it_end) {
 			(*it)->markUsed(*this);
 		}
-#ifdef TR_RATIO
-		size_t& ut = unique_targets[std::make_pair((*iter_rule)->wordform, (*iter_rule)->target)];
-		++ut;
-		max_target = std::max(max_target, ut);
-#endif
 	}
 
-#ifdef TR_RATIO
-	double avg = rule_by_number.size() / static_cast<double>(unique_targets.size());
-	double vsum = 0.0;
-	for (const auto& v : unique_targets) {
-		vsum += std::pow(v.second - avg, 2.0);
-	}
-	double var = vsum / unique_targets.size();
-
-	u_fprintf(ux_stderr, "Target:Rule ratios: %u rules, %u unique targets, %u max rules, %f average, %f variance, %f stddev\n", rule_by_number.size(), unique_targets.size(), max_target, avg, var, std::sqrt(var));
-	u_fflush(ux_stderr);
-#endif
-
-	if (delimiters) {
-		delimiters->markUsed(*this);
-	}
-	if (soft_delimiters) {
-		soft_delimiters->markUsed(*this);
-	}
+	if (!is_binary) {
+		if (delimiters) {
+			delimiters->markUsed(*this);
+		}
+		if (soft_delimiters) {
+			soft_delimiters->markUsed(*this);
+		}
 
-	// This is only necessary due to binary grammars.
-	// Sets used in unused templates may otherwise crash the loading of a binary grammar.
-	foreach (std::vector<ContextualTest*>, template_list, tmpls, tmpls_end) {
-		(*tmpls)->markUsed(*this);
+		contexts_t tosave;
+		for (BOOST_AUTO(cntx, contexts.begin()); cntx != contexts.end(); ++cntx) {
+			if (cntx->second->is_used) {
+				tosave[cntx->first] = cntx->second;
+				continue;
+			}
+			delete cntx->second;
+		}
+		contexts.swap(tosave);
 	}
 
 	if (unused_sets) {
@@ -727,12 +707,17 @@ void Grammar::reindex(bool unused_sets) {
 		}
 	}
 
-	foreach (Setuint32HashMap, sets_by_contents, iter_sets, iter_sets_end) {
-		if (iter_sets->second->type & ST_USED) {
-			iter_sets->second->reindex(*this);
-			indexSets(iter_sets->first, iter_sets->second);
+	if (!is_binary) {
+		boost_foreach (Set *set, sets_list) {
+			set->reindex(*this);
+		}
+		boost_foreach (Set *set, sets_list) {
+			setAdjustSets(set);
 		}
 	}
+	boost_foreach (Set *set, sets_list) {
+		indexSets(set->number, set);
+	}
 
 	uint32SortedVector sects;
 
@@ -751,13 +736,41 @@ void Grammar::reindex(bool unused_sets) {
 			rules.push_back(*iter_rule);
 		}
 		if ((*iter_rule)->target) {
-			indexSetToRule((*iter_rule)->number, getSet((*iter_rule)->target));
+			Set *set = 0;
+			if (is_binary) {
+				set = sets_list[(*iter_rule)->target];
+			}
+			else {
+				set = sets_by_contents.find((*iter_rule)->target)->second;
+				(*iter_rule)->target = set->number;
+			}
+			indexSetToRule((*iter_rule)->number, set);
 			rules_by_set[(*iter_rule)->target].insert((*iter_rule)->number);
 		}
 		else {
 			u_fprintf(ux_stderr, "Warning: Rule on line %u had no target.\n", (*iter_rule)->line);
 			u_fflush(ux_stderr);
 		}
+		if (is_binary) {
+			continue;
+		}
+		if ((*iter_rule)->childset1) {
+			Set *set = sets_by_contents.find((*iter_rule)->childset1)->second;
+			(*iter_rule)->childset1 = set->number;
+		}
+		if ((*iter_rule)->childset2) {
+			Set *set = sets_by_contents.find((*iter_rule)->childset2)->second;
+			(*iter_rule)->childset2 = set->number;
+		}
+		if ((*iter_rule)->dep_target) {
+			contextAdjustTarget((*iter_rule)->dep_target);
+		}
+		boost_foreach (ContextualTest *test, (*iter_rule)->tests) {
+			contextAdjustTarget(test);
+		}
+		boost_foreach (ContextualTest *test, (*iter_rule)->dep_tests) {
+			contextAdjustTarget(test);
+		}
 	}
 
 	sections.insert(sections.end(), sects.begin(), sects.end());
@@ -768,6 +781,39 @@ void Grammar::reindex(bool unused_sets) {
 	if (rules_by_tag.find(tag_any) != rules_by_tag.end()) {
 		rules_any = &rules_by_tag[tag_any];
 	}
+
+	sets_by_contents.clear();
+
+	boost_foreach (Set *to, sets_list) {
+		if (to->type & ST_STATIC) {
+			uint32_t nhash = hash_value(to->name);
+			const uint32_t cnum = to->number;
+
+			if (sets_by_name.find(nhash) == sets_by_name.end()) {
+				sets_by_name[nhash] = cnum;
+			}
+			else if (cnum != sets_list[sets_by_name.find(nhash)->second]->number) {
+				Set *a = sets_list[sets_by_name.find(nhash)->second];
+				if (a->name == to->name) {
+					u_fprintf(ux_stderr, "Error: Static set %S already defined. Redefinition attempted!\n", a->name.c_str());
+					CG3Quit(1);
+				}
+				else {
+					for (uint32_t seed=0 ; seed<1000 ; ++seed) {
+						if (sets_by_name.find(nhash+seed) == sets_by_name.end()) {
+							if (verbosity_level > 0) {
+								u_fprintf(ux_stderr, "Warning: Static set %S got hash seed %u.\n", to->name.c_str(), seed);
+								u_fflush(ux_stderr);
+							}
+							set_name_seeds[to->name] = seed;
+							sets_by_name[nhash+seed] = cnum;
+							break;
+						}
+					}
+				}
+			}
+		}
+	}
 }
 
 inline void trie_indexToRule(const trie_t& trie, Grammar& grammar, uint32_t r) {
@@ -789,7 +835,7 @@ void Grammar::indexSetToRule(uint32_t r, Set *s) {
 	trie_indexToRule(s->trie_special, *this, r);
 
 	for (uint32_t i=0 ; i<s->sets.size() ; ++i) {
-		Set *set = sets_by_contents.find(s->sets[i])->second;
+		Set *set = sets_list[s->sets[i]];
 		indexSetToRule(r, set);
 	}
 }
@@ -817,7 +863,7 @@ void Grammar::indexSets(uint32_t r, Set *s) {
 	trie_indexToSet(s->trie_special, *this, r);
 
 	for (uint32_t i=0 ; i<s->sets.size() ; ++i) {
-		Set *set = sets_by_contents.find(s->sets[i])->second;
+		Set *set = sets_list[s->sets[i]];
 		indexSets(r, set);
 	}
 }
@@ -826,4 +872,47 @@ void Grammar::indexTagToSet(uint32_t t, uint32_t r) {
 	sets_by_tag[t].insert(r);
 }
 
+void Grammar::setAdjustSets(Set *s) {
+	if (!(s->type & ST_USED)) {
+		return;
+	}
+	s->type &= ~ST_USED;
+
+	for (uint32_t i = 0; i<s->sets.size(); ++i) {
+		Set *set = sets_by_contents.find(s->sets[i])->second;
+		s->sets[i] = set->number;
+		setAdjustSets(set);
+	}
+}
+
+void Grammar::contextAdjustTarget(ContextualTest *test) {
+	if (!test->is_used) {
+		return;
+	}
+	test->is_used = false;
+
+	if (test->target) {
+		Set *set = sets_by_contents.find(test->target)->second;
+		test->target = set->number;
+	}
+	if (test->barrier) {
+		Set *set = sets_by_contents.find(test->barrier)->second;
+		test->barrier = set->number;
+	}
+	if (test->cbarrier) {
+		Set *set = sets_by_contents.find(test->cbarrier)->second;
+		test->cbarrier = set->number;
+	}
+
+	boost_foreach (ContextualTest *tor, test->ors) {
+		contextAdjustTarget(tor);
+	}
+	if (test->tmpl) {
+		contextAdjustTarget(test->tmpl);
+	}
+	if (test->linked) {
+		contextAdjustTarget(test->linked);
+	}
+}
+
 }
diff --git a/src/Grammar.hpp b/src/Grammar.hpp
index c6c352e..ca8e0a1 100644
--- a/src/Grammar.hpp
+++ b/src/Grammar.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -68,11 +68,9 @@ namespace CG3 {
 		typedef TagSortedVector icase_tags_t;
 		icase_tags_t icase_tags;
 
-		std::vector<ContextualTest*> template_list;
 		typedef stdext::hash_map<uint32_t, ContextualTest*> contexts_t;
 		contexts_t templates;
 		contexts_t contexts;
-		ContextVector contexts_list;
 
 		typedef stdext::hash_map<uint32_t, uint32IntervalVector> rules_by_set_t;
 		rules_by_set_t rules_by_set;
@@ -88,8 +86,9 @@ namespace CG3 {
 		Set *soft_delimiters;
 		uint32_t tag_any;
 		uint32Vector preferred_targets;
-		uint32Map parentheses;
-		uint32Map parentheses_reverse;
+		typedef bc::flat_map<uint32_t,uint32_t> parentheses_t;
+		parentheses_t parentheses;
+		parentheses_t parentheses_reverse;
 
 		uint32Vector sections;
 		uint32FlatHashMap anchors;
@@ -112,6 +111,7 @@ namespace CG3 {
 		void destroySet(Set *set);
 		void addSetToList(Set *s);
 		Set *parseSet(const UChar *name);
+		void allocateDummySet();
 
 		void addAnchor(const UChar *to, uint32_t at, bool primary = false);
 
@@ -136,6 +136,8 @@ namespace CG3 {
 		void indexTagToRule(uint32_t, uint32_t);
 		void indexSets(uint32_t, Set*);
 		void indexTagToSet(uint32_t, uint32_t);
+		void setAdjustSets(Set*);
+		void contextAdjustTarget(ContextualTest*);
 	};
 
 }
diff --git a/src/GrammarApplicator.cpp b/src/GrammarApplicator.cpp
index 5c6bb62..3103bf9 100644
--- a/src/GrammarApplicator.cpp
+++ b/src/GrammarApplicator.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -127,8 +127,12 @@ GrammarApplicator::~GrammarApplicator() {
 }
 
 void GrammarApplicator::resetIndexes() {
-	index_readingSet_yes.clear();
-	index_readingSet_no.clear();
+	boost_foreach (uint32FlatHashSet& sv, index_readingSet_yes) {
+		sv.clear();
+	}
+	boost_foreach (uint32FlatHashSet& sv, index_readingSet_no) {
+		sv.clear();
+	}
 	index_regexp_yes.clear();
 	index_regexp_no.clear();
 	index_icase_yes.clear();
@@ -142,6 +146,11 @@ void GrammarApplicator::setGrammar(Grammar *res) {
 	tag_end = addTag(stringbits[S_ENDTAG].getTerminatedBuffer());
 	begintag = tag_begin->hash;
 	endtag = tag_end->hash;
+
+	index_readingSet_yes.clear();
+	index_readingSet_yes.resize(grammar->sets_list.size());
+	index_readingSet_no.clear();
+	index_readingSet_no.resize(grammar->sets_list.size());
 }
 
 void GrammarApplicator::index() {
diff --git a/src/GrammarApplicator.hpp b/src/GrammarApplicator.hpp
index 69d704b..1fee4b9 100644
--- a/src/GrammarApplicator.hpp
+++ b/src/GrammarApplicator.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -187,8 +187,8 @@ namespace CG3 {
 		uint32FlatHashSet index_regexp_no;
 		uint32FlatHashSet index_icase_yes;
 		uint32FlatHashSet index_icase_no;
-		uint32FlatHashSet index_readingSet_yes;
-		uint32FlatHashSet index_readingSet_no;
+		std::vector<uint32FlatHashSet> index_readingSet_yes;
+		std::vector<uint32FlatHashSet> index_readingSet_no;
 		uint32FlatHashSet index_ruleCohort_no;
 		void resetIndexes();
 	
diff --git a/src/GrammarApplicator_matchSet.cpp b/src/GrammarApplicator_matchSet.cpp
index f85da50..7b82fcb 100644
--- a/src/GrammarApplicator_matchSet.cpp
+++ b/src/GrammarApplicator_matchSet.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -190,8 +190,8 @@ uint32_t GrammarApplicator::doesTagMatchReading(const Reading& reading, const Ta
 	}
 	else if (tag.type & T_SET) {
 		uint32_t sh = hash_value(tag.tag);
-		Set *s = grammar->getSet(sh);
-		match = doesSetMatchReading(reading, s->hash, bypass_index, unif_mode);
+		sh = grammar->sets_by_name.find(sh)->second;
+		match = doesSetMatchReading(reading, sh, bypass_index, unif_mode);
 	}
 	else if (tag.type & T_VARSTRING) {
 		const Tag *nt = generateVarstringTag(&tag);
@@ -440,11 +440,11 @@ bool GrammarApplicator::doesSetMatchReading_trie(const Reading& reading, const S
 			}
 			if (kv.second.terminal) {
 				if (unif_mode) {
-					BOOST_AUTO(it, unif_tags->find(theset.hash));
+					BOOST_AUTO(it, unif_tags->find(theset.number));
 					if (it != unif_tags->end() && it->second != &kv) {
 						continue;
 					}
-					(*unif_tags)[theset.hash] = &kv;
+					(*unif_tags)[theset.number] = &kv;
 				}
 				return true;
 			}
@@ -485,12 +485,12 @@ bool GrammarApplicator::doesSetMatchReading_tags(const Reading& reading, const S
 			if (*oiter == iiter->first->hash) {
 				if (iiter->second.terminal) {
 					if (unif_mode) {
-						BOOST_AUTO(it, unif_tags->find(theset.hash));
+						BOOST_AUTO(it, unif_tags->find(theset.number));
 						if (it != unif_tags->end() && it->second != &*iiter) {
 							++iiter;
 							continue;
 						}
-						(*unif_tags)[theset.hash] = &*iiter;
+						(*unif_tags)[theset.number] = &*iiter;
 					}
 					retval = true;
 					break;
@@ -533,12 +533,11 @@ bool GrammarApplicator::doesSetMatchReading(const Reading& reading, const uint32
 	// These indexes are cleared every ((num_windows+4)*2+1) windows to avoid memory ballooning.
 	// Only 30% of tests get past this.
 	// ToDo: This is not good enough...while numeric tags are special, their failures can be indexed.
-	uint32_t ih = hash_value(reading.hash, set);
 	if (!bypass_index && !unif_mode) {
-		if (index_matches(index_readingSet_no, ih)) {
+		if (index_readingSet_no[set].find(reading.hash) != index_readingSet_no[set].end()) {
 			return false;
 		}
-		else if (index_matches(index_readingSet_yes, ih)) {
+		if (index_readingSet_yes[set].find(reading.hash) != index_readingSet_yes[set].end()) {
 			return true;
 		}
 	}
@@ -551,8 +550,7 @@ bool GrammarApplicator::doesSetMatchReading(const Reading& reading, const uint32
 	}
 
 	// ToDo: Make all places have Set* directly so we don't need to perform this lookup.
-	Setuint32HashMap::const_iterator iter = grammar->sets_by_contents.find(set);
-	const Set& theset = *(iter->second);
+	const Set& theset = *grammar->sets_list[set];
 
 	// The (*) set always matches.
 	if (theset.type & ST_ANY) {
@@ -567,14 +565,12 @@ bool GrammarApplicator::doesSetMatchReading(const Reading& reading, const uint32
 		// ToDo: Handle multiple active &&sets at a time.
 		// First time, figure out all the sub-sets that match the reading and store them for later comparison
 		if (unif_sets_firstrun) {
-			Setuint32HashMap::const_iterator iter = grammar->sets_by_contents.find(theset.sets[0]);
-			const Set& uset = *(iter->second);
+			const Set& uset = *grammar->sets_list[theset.sets[0]];
 			const size_t size = uset.sets.size();
 			for (size_t i=0;i<size;++i) {
-				iter = grammar->sets_by_contents.find(uset.sets[i]);
-				const Set& tset = *(iter->second);
-				if (doesSetMatchReading(reading, tset.hash, bypass_index, ((theset.type & ST_TAG_UNIFY)!=0)|unif_mode)) {
-					unif_sets->insert(tset.hash);
+				const Set& tset = *grammar->sets_list[uset.sets[i]];
+				if (doesSetMatchReading(reading, tset.number, bypass_index, ((theset.type & ST_TAG_UNIFY)!=0)|unif_mode)) {
+					unif_sets->insert(tset.number);
 				}
 			}
 			retval = !unif_sets->empty();
@@ -674,11 +670,11 @@ bool GrammarApplicator::doesSetMatchReading(const Reading& reading, const uint32
 
 	// Store the result in the indexes in hopes that later runs can pull it directly from them.
 	if (retval) {
-		index_readingSet_yes.insert(ih);
+		index_readingSet_yes[set].insert(reading.hash);
 	}
 	else {
 		if (!(theset.type & ST_TAG_UNIFY) && !unif_mode) {
-			index_readingSet_no.insert(ih);
+			index_readingSet_no[set].insert(reading.hash);
 		}
 	}
 
@@ -691,7 +687,7 @@ inline void GrammarApplicator::doesSetMatchCohortHelper(std::vector<Reading*>& r
 		if (!reading) {
 			continue;
 		}
-		if (doesSetMatchReading(*reading, theset->hash, (theset->type & (ST_CHILD_UNIFY|ST_SPECIAL)) != 0)) {
+		if (doesSetMatchReading(*reading, theset->number, (theset->type & (ST_CHILD_UNIFY|ST_SPECIAL)) != 0)) {
 			rv.push_back(reading);
 			if (!(options & MASK_POS_CDEPREL)) {
 				break;
@@ -720,7 +716,7 @@ std::vector<Reading*> GrammarApplicator::doesSetMatchCohort(Cohort& cohort, cons
 		return rv;
 	}
 
-	const Set *theset = grammar->sets_by_contents.find(set)->second;
+	const Set *theset = grammar->sets_list[set];
 	doesSetMatchCohortHelper(rv, cohort.readings, theset, test, options);
 	if ((options & POS_LOOK_DELETED) && _check_options(rv, options, cohort.readings.size())) {
 		doesSetMatchCohortHelper(rv, cohort.deleted, theset, test, options);
@@ -747,7 +743,7 @@ bool GrammarApplicator::doesSetMatchCohortNormal_helper(ReadingList& readings, c
 				continue;
 			}
 		}
-		if (doesSetMatchReading(*reading, theset->hash, (theset->type & (ST_CHILD_UNIFY|ST_SPECIAL)) != 0)) {
+		if (doesSetMatchReading(*reading, theset->number, (theset->type & (ST_CHILD_UNIFY|ST_SPECIAL)) != 0)) {
 			return true;
 		}
 	}
@@ -762,8 +758,8 @@ bool GrammarApplicator::doesSetMatchCohortNormal(Cohort& cohort, const uint32_t
 		return false;
 	}
 	bool retval = false;
-	const Set *theset = grammar->sets_by_contents.find(set)->second;
-	if (cohort.wread && doesSetMatchReading(*cohort.wread, theset->hash, (theset->type & (ST_CHILD_UNIFY|ST_SPECIAL)) != 0)) {
+	const Set *theset = grammar->sets_list[set];
+	if (cohort.wread && doesSetMatchReading(*cohort.wread, theset->number, (theset->type & (ST_CHILD_UNIFY|ST_SPECIAL)) != 0)) {
 		retval = true;
 	}
 	if (doesSetMatchCohortNormal_helper(cohort.readings, theset, test)) {
@@ -793,7 +789,7 @@ bool GrammarApplicator::doesSetMatchCohortCareful_helper(ReadingList& readings,
 				return false;
 			}
 		}
-		if (!doesSetMatchReading(*reading, theset->hash, (theset->type & (ST_CHILD_UNIFY|ST_SPECIAL)) != 0)) {
+		if (!doesSetMatchReading(*reading, theset->number, (theset->type & (ST_CHILD_UNIFY|ST_SPECIAL)) != 0)) {
 			return false;
 		}
 	}
@@ -808,7 +804,7 @@ bool GrammarApplicator::doesSetMatchCohortCareful(Cohort& cohort, const uint32_t
 		return false;
 	}
 	bool retval = true;
-	const Set *theset = grammar->sets_by_contents.find(set)->second;
+	const Set *theset = grammar->sets_list[set];
 	if (!doesSetMatchCohortCareful_helper(cohort.readings, theset, test)) {
 		retval = false;
 	}
diff --git a/src/GrammarApplicator_reflow.cpp b/src/GrammarApplicator_reflow.cpp
index e98cbf4..a7fc861 100644
--- a/src/GrammarApplicator_reflow.cpp
+++ b/src/GrammarApplicator_reflow.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -554,10 +554,25 @@ bool GrammarApplicator::unmapReading(Reading& reading, const uint32_t rule) {
 }
 
 void GrammarApplicator::splitMappings(TagList& mappings, Cohort& cohort, Reading& reading, bool mapped) {
+	for (TagList::iterator it = mappings.begin() ; it != mappings.end() ;) {
+		Tag *& tag = *it;
+		while (tag->type & T_VARSTRING) {
+			tag = generateVarstringTag(tag);
+		}
+		if (!(tag->type & T_MAPPING || tag->tag[0] == grammar->mapping_prefix)) {
+			addTagToReading(reading, tag);
+			it = mappings.erase(it);
+		}
+		else {
+			++it;
+		}
+	}
+
 	if (reading.mapping) {
 		mappings.push_back(reading.mapping);
 		delTagFromReading(reading, reading.mapping->hash);
 	}
+
 	Tag *tag = mappings.back();
 	mappings.pop_back();
 	size_t i = mappings.size();
diff --git a/src/GrammarApplicator_runContextualTest.cpp b/src/GrammarApplicator_runContextualTest.cpp
index 17dd9c9..5f1ecf1 100644
--- a/src/GrammarApplicator_runContextualTest.cpp
+++ b/src/GrammarApplicator_runContextualTest.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/GrammarApplicator_runGrammar.cpp b/src/GrammarApplicator_runGrammar.cpp
index a9b6a24..3cef8db 100644
--- a/src/GrammarApplicator_runGrammar.cpp
+++ b/src/GrammarApplicator_runGrammar.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -174,7 +174,7 @@ gotaline:
 			if (cSWindow && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && !did_soft_lookback) {
 				did_soft_lookback = true;
 				reverse_foreach (CohortVector, cSWindow->cohorts, iter, iter_end) {
-					if (doesSetMatchCohortNormal(**iter, grammar->soft_delimiters->hash)) {
+					if (doesSetMatchCohortNormal(**iter, grammar->soft_delimiters->number)) {
 						did_soft_lookback = false;
 						Cohort *cohort = delimitAt(*cSWindow, *iter);
 						cSWindow = cohort->parent->next;
@@ -189,7 +189,7 @@ gotaline:
 					}
 				}
 			}
-			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->hash)) {
+			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->number)) {
 				if (verbosity_level > 0) {
 					u_fprintf(ux_stderr, "Warning: Soft limit of %u cohorts reached at line %u but found suitable soft delimiter.\n", soft_limit, numLines);
 					u_fflush(ux_stderr);
@@ -206,7 +206,7 @@ gotaline:
 				numCohorts++;
 				did_soft_lookback = false;
 			}
-			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (!dep_delimit && grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->hash)))) {
+			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (!dep_delimit && grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->number)))) {
 				if (cSWindow->cohorts.size() >= hard_limit) {
 					u_fprintf(ux_stderr, "Warning: Hard limit of %u cohorts reached at line %u - forcing break.\n", hard_limit, numLines);
 					u_fflush(ux_stderr);
diff --git a/src/GrammarApplicator_runRules.cpp b/src/GrammarApplicator_runRules.cpp
index c095a3c..ffae447 100644
--- a/src/GrammarApplicator_runRules.cpp
+++ b/src/GrammarApplicator_runRules.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -106,28 +106,28 @@ void GrammarApplicator::indexSingleWindow(SingleWindow& current) {
 TagList GrammarApplicator::getTagList(const Set& theSet, bool unif_mode) const {
 	TagList theTags;
 	if (theSet.type & ST_SET_UNIFY) {
-		const Set& pSet = *(grammar->getSet(theSet.sets[0]));
+		const Set& pSet = *(grammar->sets_list[theSet.sets[0]]);
 		const_foreach (uint32Vector, pSet.sets, iter, iter_end) {
 			if (unif_sets->count(*iter)) {
-				TagList recursiveTags = getTagList(*(grammar->getSet(*iter)));
+				TagList recursiveTags = getTagList(*(grammar->sets_list[*iter]));
 				theTags.splice(theTags.end(), recursiveTags);
 			}
 		}
 	}
 	else if (theSet.type & ST_TAG_UNIFY) {
 		const_foreach (uint32Vector, theSet.sets, iter, iter_end) {
-			TagList recursiveTags = getTagList(*(grammar->getSet(*iter)), true);
+			TagList recursiveTags = getTagList(*(grammar->sets_list[*iter]), true);
 			theTags.splice(theTags.end(), recursiveTags);
 		}
 	}
 	else if (!theSet.sets.empty()) {
 		const_foreach (uint32Vector, theSet.sets, iter, iter_end) {
-			TagList recursiveTags = getTagList(*(grammar->getSet(*iter)), unif_mode);
+			TagList recursiveTags = getTagList(*(grammar->sets_list[*iter]), unif_mode);
 			theTags.splice(theTags.end(), recursiveTags);
 		}
 	}
 	else if (unif_mode) {
-		BOOST_AUTO(iter, unif_tags->find(theSet.hash));
+		BOOST_AUTO(iter, unif_tags->find(theSet.number));
 		if (iter != unif_tags->end()) {
 			trie_getTagList(theSet.trie, theTags, iter->second);
 			trie_getTagList(theSet.trie_special, theTags, iter->second);
@@ -220,7 +220,7 @@ uint32_t GrammarApplicator::runRulesOnSingleWindow(SingleWindow& current, const
 			tstamp = getticks();
 		}
 
-		const Set& set = *(grammar->getSet(rule.target));
+		const Set& set = *(grammar->sets_list[rule.target]);
 		grammar->lines = rule.line;
 
 		uint32ToCohortsMap::iterator csit = current.rule_to_cohorts.find(rule.number);
@@ -714,8 +714,11 @@ uint32_t GrammarApplicator::runRulesOnSingleWindow(SingleWindow& current, const
 							cReading->hit_by.push_back(rule.number);
 							cReading->noprint = false;
 							TagList mappings;
-							const_foreach (TagList, *rit, tter, tter_end) {
+							foreach (TagList, *rit, tter, tter_end) {
 								uint32_t hash = (*tter)->hash;
+								while ((*tter)->type & T_VARSTRING) {
+									*tter = generateVarstringTag(*tter);
+								}
 								if ((*tter)->type & T_MAPPING || (*tter)->tag[0] == grammar->mapping_prefix) {
 									mappings.push_back(*tter);
 								}
@@ -777,14 +780,17 @@ uint32_t GrammarApplicator::runRulesOnSingleWindow(SingleWindow& current, const
 						reading.hit_by.push_back(rule.number);
 						reading.noprint = false;
 						TagList mappings;
-						const TagList theTags = getTagList(*rule.maplist);
-						const_foreach (TagList, theTags, tter, tter_end) {
+						TagList theTags = getTagList(*rule.maplist);
+						foreach (TagList, theTags, tter, tter_end) {
 							uint32_t hash = (*tter)->hash;
+							while ((*tter)->type & T_VARSTRING) {
+								*tter = generateVarstringTag(*tter);
+							}
 							if ((*tter)->type & T_MAPPING || (*tter)->tag[0] == grammar->mapping_prefix) {
 								mappings.push_back(*tter);
 							}
 							else {
-								hash = addTagToReading(reading, hash);
+								hash = addTagToReading(reading, *tter);
 							}
 							if (updateValidRules(rules, intersects, hash, reading)) {
 								iter_rules = intersects.find(rule.number);
@@ -817,13 +823,16 @@ uint32_t GrammarApplicator::runRulesOnSingleWindow(SingleWindow& current, const
 						reflowReading(reading);
 						TagList mappings;
 						TagList theTags = getTagList(*rule.maplist);
-						const_foreach (TagList, theTags, tter, tter_end) {
+						foreach (TagList, theTags, tter, tter_end) {
 							uint32_t hash = (*tter)->hash;
+							while ((*tter)->type & T_VARSTRING) {
+								*tter = generateVarstringTag(*tter);
+							}
 							if ((*tter)->type & T_MAPPING || (*tter)->tag[0] == grammar->mapping_prefix) {
 								mappings.push_back(*tter);
 							}
 							else {
-								hash = addTagToReading(reading, hash);
+								hash = addTagToReading(reading, *tter);
 							}
 							if (updateValidRules(rules, intersects, hash, reading)) {
 								iter_rules = intersects.find(rule.number);
@@ -863,7 +872,7 @@ uint32_t GrammarApplicator::runRulesOnSingleWindow(SingleWindow& current, const
 
 						// Perform the tag removal, remembering the position of the final removed tag for use as insertion spot
 						const_foreach (TagList, theTags, tter, tter_end) {
-							if (tpos == std::numeric_limits<size_t>::max()) {
+							if (tpos >= reading.tags_list.size()) {
 								foreach (Reading::tags_list_t, reading.tags_list, tfind, tfind_end) {
 									if (*tfind == (*tter)->hash) {
 										tpos = std::distance(reading.tags_list.begin(), tfind);
@@ -885,7 +894,7 @@ uint32_t GrammarApplicator::runRulesOnSingleWindow(SingleWindow& current, const
 							index_ruleCohort_no.clear();
 							reading.hit_by.push_back(rule.number);
 							reading.noprint = false;
-							if (tpos == std::numeric_limits<size_t>::max()) {
+							if (tpos >= reading.tags_list.size()) {
 								tpos = reading.tags_list.size() - 1;
 							}
 							++tpos;
@@ -979,13 +988,16 @@ uint32_t GrammarApplicator::runRulesOnSingleWindow(SingleWindow& current, const
 							cReading->hit_by.push_back(rule.number);
 							cReading->noprint = false;
 							TagList mappings;
-							const_foreach (TagList, *rit, tter, tter_end) {
+							foreach (TagList, *rit, tter, tter_end) {
 								uint32_t hash = (*tter)->hash;
+								while ((*tter)->type & T_VARSTRING) {
+									*tter = generateVarstringTag(*tter);
+								}
 								if ((*tter)->type & T_MAPPING || (*tter)->tag[0] == grammar->mapping_prefix) {
 									mappings.push_back(*tter);
 								}
 								else {
-									hash = addTagToReading(*cReading, hash);
+									hash = addTagToReading(*cReading, *tter);
 								}
 								if (updateValidRules(rules, intersects, hash, *cReading)) {
 									iter_rules = intersects.find(rule.number);
@@ -1031,13 +1043,16 @@ uint32_t GrammarApplicator::runRulesOnSingleWindow(SingleWindow& current, const
 
 						TagList mappings;
 						TagList theTags = getTagList(*rule.maplist);
-						const_foreach (TagList, theTags, tter, tter_end) {
+						foreach (TagList, theTags, tter, tter_end) {
 							uint32_t hash = (*tter)->hash;
+							while ((*tter)->type & T_VARSTRING) {
+								*tter = generateVarstringTag(*tter);
+							}
 							if ((*tter)->type & T_MAPPING || (*tter)->tag[0] == grammar->mapping_prefix) {
 								mappings.push_back(*tter);
 							}
 							else {
-								hash = addTagToReading(*cReading, hash);
+								hash = addTagToReading(*cReading, *tter);
 							}
 							if (updateValidRules(rules, intersects, hash, reading)) {
 								iter_rules = intersects.find(rule.number);
@@ -1474,7 +1489,7 @@ void GrammarApplicator::runGrammarOnWindow() {
 			if (c->is_pleft == 0) {
 				continue;
 			}
-			uint32Map::const_iterator p = grammar->parentheses.find(c->is_pleft);
+			Grammar::parentheses_t::const_iterator p = grammar->parentheses.find(c->is_pleft);
 			if (p != grammar->parentheses.end()) {
 				CohortVector::iterator right = iter.base();
 				--right;
diff --git a/src/GrammarWriter.cpp b/src/GrammarWriter.cpp
index dcf664a..ae9b7ff 100644
--- a/src/GrammarWriter.cpp
+++ b/src/GrammarWriter.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -37,7 +37,7 @@ GrammarWriter::~GrammarWriter() {
 }
 
 void GrammarWriter::printSet(UFILE *output, const Set& curset) {
-	if (used_sets.find(curset.hash) != used_sets.end()) {
+	if (used_sets.find(curset.number) != used_sets.end()) {
 		return;
 	}
 
@@ -50,7 +50,7 @@ void GrammarWriter::printSet(UFILE *output, const Set& curset) {
 				u_fprintf(output, "#List Matched: %u ; NoMatch: %u ; TotalTime: %f\n", curset.num_match, curset.num_fail, curset.total_time);
 			}
 		}
-		used_sets.insert(curset.hash);
+		used_sets.insert(curset.number);
 		u_fprintf(output, "LIST %S = ", curset.name.c_str());
 		std::set<TagVector> tagsets[] = { trie_getTagsOrdered(curset.trie), trie_getTagsOrdered(curset.trie_special) };
 		boost_foreach (const std::set<TagVector>& tvs, tagsets) {
@@ -70,9 +70,9 @@ void GrammarWriter::printSet(UFILE *output, const Set& curset) {
 		u_fprintf(output, " ;\n");
 	}
 	else {
-		used_sets.insert(curset.hash);
+		used_sets.insert(curset.number);
 		for (uint32_t i=0;i<curset.sets.size();i++) {
-			printSet(output, *(grammar->sets_by_contents.find(curset.sets[i])->second));
+			printSet(output, *(grammar->sets_list[curset.sets[i]]));
 		}
 		if (statistics) {
 			if (ceil(curset.total_time) == floor(curset.total_time)) {
@@ -87,9 +87,9 @@ void GrammarWriter::printSet(UFILE *output, const Set& curset) {
 			u_fprintf(output, "# ");
 		}
 		u_fprintf(output, "SET %S = ", n);
-		u_fprintf(output, "%S ", grammar->sets_by_contents.find(curset.sets[0])->second->name.c_str());
+		u_fprintf(output, "%S ", grammar->sets_list[curset.sets[0]]->name.c_str());
 		for (uint32_t i=0;i<curset.sets.size()-1;i++) {
-			u_fprintf(output, "%S %S ", stringbits[curset.set_ops[i]].getTerminatedBuffer(), grammar->sets_by_contents.find(curset.sets[i+1])->second->name.c_str());
+			u_fprintf(output, "%S %S ", stringbits[curset.set_ops[i]].getTerminatedBuffer(), grammar->sets_list[curset.sets[i+1]]->name.c_str());
 		}
 		u_fprintf(output, " ;\n\n");
 	}
@@ -149,26 +149,23 @@ int GrammarWriter::writeGrammar(UFILE *output) {
 	u_fprintf(output, "\n");
 
 	used_sets.clear();
-	Setuint32HashMap::const_iterator set_iter;
-	for (set_iter = grammar->sets_by_contents.begin() ; set_iter != grammar->sets_by_contents.end() ; set_iter++) {
-		Set *s = set_iter->second;
+	boost_foreach (Set *s, grammar->sets_list) {
 		if (s->name[0] == '_' && s->name[1] == 'G' && s->name[2] == '_') {
 			s->name.insert(s->name.begin(), '3');
 			s->name.insert(s->name.begin(), 'G');
 			s->name.insert(s->name.begin(), 'C');
 		}
 	}
-	for (set_iter = grammar->sets_by_contents.begin() ; set_iter != grammar->sets_by_contents.end() ; set_iter++) {
-		if (set_iter->second->type & ST_USED) {
-			printSet(output, *(set_iter->second));
+	boost_foreach (Set *s, grammar->sets_list) {
+		if (s->type & ST_USED) {
+			printSet(output, *s);
 		}
 	}
 	u_fprintf(output, "\n");
 
-	std::vector<ContextualTest*>::const_iterator tmpl_iter;
-	for (tmpl_iter = grammar->template_list.begin() ; tmpl_iter != grammar->template_list.end() ; tmpl_iter++) {
-		u_fprintf(output, "TEMPLATE %u = ", (*tmpl_iter)->name);
-		printContextualTest(output, **tmpl_iter);
+	for (BOOST_AUTO(cntx, grammar->templates.begin()); cntx != grammar->templates.end(); ++cntx) {
+		u_fprintf(output, "TEMPLATE %u = ", cntx->second->hash);
+		printContextualTest(output, *cntx->second);
 		u_fprintf(output, " ;\n");
 	}
 	u_fprintf(output, "\n");
@@ -264,7 +261,7 @@ void GrammarWriter::printRule(UFILE *to, const Rule& rule) {
 	}
 
 	if (rule.target) {
-		u_fprintf(to, "%S ", grammar->sets_by_contents.find(rule.target)->second->name.c_str());
+		u_fprintf(to, "%S ", grammar->sets_list[rule.target]->name.c_str());
 	}
 
 	const_foreach (ContextList, rule.tests, it, it_end) {
@@ -295,7 +292,7 @@ void GrammarWriter::printContextualTest(UFILE *to, const ContextualTest& test) {
 		}
 	}
 	if (test.tmpl) {
-		u_fprintf(to, "T:%u ", test.tmpl->name);
+		u_fprintf(to, "T:%u ", test.tmpl->hash);
 	}
 	else if (!test.ors.empty()) {
 		std::list<ContextualTest*>::const_iterator iter;
@@ -395,13 +392,13 @@ void GrammarWriter::printContextualTest(UFILE *to, const ContextualTest& test) {
 		u_fprintf(to, " ");
 
 		if (test.target) {
-			u_fprintf(to, "%S ", grammar->sets_by_contents.find(test.target)->second->name.c_str());
+			u_fprintf(to, "%S ", grammar->sets_list[test.target]->name.c_str());
 		}
 		if (test.cbarrier) {
-			u_fprintf(to, "CBARRIER %S ", grammar->sets_by_contents.find(test.cbarrier)->second->name.c_str());
+			u_fprintf(to, "CBARRIER %S ", grammar->sets_list[test.cbarrier]->name.c_str());
 		}
 		if (test.barrier) {
-			u_fprintf(to, "BARRIER %S ", grammar->sets_by_contents.find(test.barrier)->second->name.c_str());
+			u_fprintf(to, "BARRIER %S ", grammar->sets_list[test.barrier]->name.c_str());
 		}
 	}
 
diff --git a/src/GrammarWriter.hpp b/src/GrammarWriter.hpp
index 23953f1..982052e 100644
--- a/src/GrammarWriter.hpp
+++ b/src/GrammarWriter.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/IGrammarParser.hpp b/src/IGrammarParser.hpp
index e2f6035..e8e8402 100644
--- a/src/IGrammarParser.hpp
+++ b/src/IGrammarParser.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -37,6 +37,7 @@ namespace CG3 {
 	protected:
 		UFILE *ux_stderr;
 		Grammar *result;
+		uint32_t verbosity;
 	};
 }
 
diff --git a/src/NicelineApplicator.cpp b/src/NicelineApplicator.cpp
index f712deb..e4420b0 100644
--- a/src/NicelineApplicator.cpp
+++ b/src/NicelineApplicator.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -139,7 +139,7 @@ gotaline:
 			if (cSWindow && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && !did_soft_lookback) {
 				did_soft_lookback = true;
 				reverse_foreach (CohortVector, cSWindow->cohorts, iter, iter_end) {
-					if (doesSetMatchCohortNormal(**iter, grammar->soft_delimiters->hash)) {
+					if (doesSetMatchCohortNormal(**iter, grammar->soft_delimiters->number)) {
 						did_soft_lookback = false;
 						Cohort *cohort = delimitAt(*cSWindow, *iter);
 						cSWindow = cohort->parent->next;
@@ -154,7 +154,7 @@ gotaline:
 					}
 				}
 			}
-			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->hash)) {
+			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->number)) {
 				if (verbosity_level > 0) {
 					u_fprintf(ux_stderr, "Warning: Soft limit of %u cohorts reached at line %u but found suitable soft delimiter.\n", soft_limit, numLines);
 					u_fflush(ux_stderr);
@@ -170,7 +170,7 @@ gotaline:
 				numCohorts++;
 				did_soft_lookback = false;
 			}
-			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (!dep_delimit && grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->hash)))) {
+			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (!dep_delimit && grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->number)))) {
 				if (cSWindow->cohorts.size() >= hard_limit) {
 					u_fprintf(ux_stderr, "Warning: Hard limit of %u cohorts reached at line %u - forcing break.\n", hard_limit, numLines);
 					u_fflush(ux_stderr);
diff --git a/src/NicelineApplicator.hpp b/src/NicelineApplicator.hpp
index 5fcf9b1..dcc028e 100644
--- a/src/NicelineApplicator.hpp
+++ b/src/NicelineApplicator.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/PlaintextApplicator.cpp b/src/PlaintextApplicator.cpp
index 6c584a9..5e21bfb 100644
--- a/src/PlaintextApplicator.cpp
+++ b/src/PlaintextApplicator.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -125,7 +125,7 @@ gotaline:
 			if (cSWindow && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && !did_soft_lookback) {
 				did_soft_lookback = true;
 				reverse_foreach (CohortVector, cSWindow->cohorts, iter, iter_end) {
-					if (doesSetMatchCohortNormal(**iter, grammar->soft_delimiters->hash)) {
+					if (doesSetMatchCohortNormal(**iter, grammar->soft_delimiters->number)) {
 						did_soft_lookback = false;
 						Cohort *cohort = delimitAt(*cSWindow, *iter);
 						cSWindow = cohort->parent->next;
@@ -140,7 +140,7 @@ gotaline:
 					}
 				}
 			}
-			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->hash)) {
+			if (cCohort && cSWindow->cohorts.size() >= soft_limit && grammar->soft_delimiters && doesSetMatchCohortNormal(*cCohort, grammar->soft_delimiters->number)) {
 				if (verbosity_level > 0) {
 					u_fprintf(ux_stderr, "Warning: Soft limit of %u cohorts reached at line %u but found suitable soft delimiter.\n", soft_limit, numLines);
 					u_fflush(ux_stderr);
@@ -157,7 +157,7 @@ gotaline:
 				numCohorts++;
 				did_soft_lookback = false;
 			}
-			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (!dep_delimit && grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->hash)))) {
+			if (cCohort && (cSWindow->cohorts.size() >= hard_limit || (!dep_delimit && grammar->delimiters && doesSetMatchCohortNormal(*cCohort, grammar->delimiters->number)))) {
 				if (cSWindow->cohorts.size() >= hard_limit) {
 					u_fprintf(ux_stderr, "Warning: Hard limit of %u cohorts reached at line %u - forcing break.\n", hard_limit, numLines);
 					u_fflush(ux_stderr);
diff --git a/src/PlaintextApplicator.hpp b/src/PlaintextApplicator.hpp
index 8106a38..d67935a 100644
--- a/src/PlaintextApplicator.hpp
+++ b/src/PlaintextApplicator.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Reading.cpp b/src/Reading.cpp
index 969d85a..b265eab 100644
--- a/src/Reading.cpp
+++ b/src/Reading.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Reading.hpp b/src/Reading.hpp
index 87c98c5..4f4abfd 100644
--- a/src/Reading.hpp
+++ b/src/Reading.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Rule.cpp b/src/Rule.cpp
index 0e630b6..1ea3d30 100644
--- a/src/Rule.cpp
+++ b/src/Rule.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -86,10 +86,6 @@ void Rule::resetStatistics() {
 	total_time = 0;
 }
 
-inline bool isSetSpecial(uint32_t s, const Grammar& g) {
-	return s && (g.getSet(s)->type & ST_SPECIAL);
-}
-
 bool Rule::cmp_quality(const Rule *a, const Rule *b) {
 	return a->total_time > b->total_time;
 }
diff --git a/src/Rule.hpp b/src/Rule.hpp
index 297c62b..34a1e5c 100644
--- a/src/Rule.hpp
+++ b/src/Rule.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Set.cpp b/src/Set.cpp
index 28c2b63..dc41672 100644
--- a/src/Set.cpp
+++ b/src/Set.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Set.hpp b/src/Set.hpp
index 088df7f..1cf20bd 100644
--- a/src/Set.hpp
+++ b/src/Set.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/SingleWindow.cpp b/src/SingleWindow.cpp
index f48188c..3063ce3 100644
--- a/src/SingleWindow.cpp
+++ b/src/SingleWindow.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/SingleWindow.hpp b/src/SingleWindow.hpp
index 4098347..23da79a 100644
--- a/src/SingleWindow.hpp
+++ b/src/SingleWindow.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Strings.cpp b/src/Strings.cpp
index a3b15b7..6c4e7d9 100644
--- a/src/Strings.cpp
+++ b/src/Strings.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Strings.hpp b/src/Strings.hpp
index 07cf754..6a1115b 100644
--- a/src/Strings.hpp
+++ b/src/Strings.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Tag.cpp b/src/Tag.cpp
index 6b53440..4444346 100644
--- a/src/Tag.cpp
+++ b/src/Tag.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Tag.hpp b/src/Tag.hpp
index 4703e87..a42308f 100644
--- a/src/Tag.hpp
+++ b/src/Tag.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/TagTrie.hpp b/src/TagTrie.hpp
index 1a0396e..1b1950b 100644
--- a/src/TagTrie.hpp
+++ b/src/TagTrie.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/TextualParser.cpp b/src/TextualParser.cpp
index 1e9ace4..f35e224 100644
--- a/src/TextualParser.cpp
+++ b/src/TextualParser.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -205,7 +205,11 @@ Set *TextualParser::parseSetInline(UChar *& p, Set *s) {
 					}
 					++p;
 
-					if (tags.size() == 1) {
+					if (tags.size() == 0) {
+						u_fprintf(ux_stderr, "Error: Empty inline set on line %u! Use (*) if you want to replace with nothing.\n", result->lines);
+						incErrorCount();
+					}
+					else if (tags.size() == 1) {
 						result->addTagToSet(tags[0], set_c);
 					}
 					else {
@@ -1974,7 +1978,6 @@ int TextualParser::parseFromUChar(UChar *input, const char *fname) {
 			ptrdiff_t c = n - p;
 			u_strncpy(&gbuffers[0][0], p, c);
 			gbuffers[0][c] = 0;
-			uint32_t cn = hash_value(&gbuffers[0][0]);
 			UString name(&gbuffers[0][0]);
 			p = n;
 			result->lines += SKIPWS(p, '=');
@@ -1986,7 +1989,6 @@ int TextualParser::parseFromUChar(UChar *input, const char *fname) {
 
 			ContextualTest *t = parseContextualTestList(p);
 			t->line = line;
-			t->name = cn;
 			result->addTemplate(t, name.c_str());
 
 			result->lines += SKIPWS(p, ';');
@@ -2174,6 +2176,8 @@ int TextualParser::parse_grammar_from_file(const char *fname, const char *loc, c
 		Tag *tany = result->allocateTag(stringbits[S_ASTERIK].getTerminatedBuffer());
 		result->tag_any = tany->hash;
 	}
+	// Create the dummy set
+	result->allocateDummySet();
 	// Create the magic set _TARGET_ containing the tag _TARGET_
 	{
 		Set *set_c = result->allocateSet();
diff --git a/src/TextualParser.hpp b/src/TextualParser.hpp
index e12ecde..4ba6c07 100644
--- a/src/TextualParser.hpp
+++ b/src/TextualParser.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Window.cpp b/src/Window.cpp
index 49ec712..ca8e08f 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/Window.hpp b/src/Window.hpp
index 7152675..3b2192a 100644
--- a/src/Window.hpp
+++ b/src/Window.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/bloomish.hpp b/src/bloomish.hpp
index cb876dc..9c8d0e7 100644
--- a/src/bloomish.hpp
+++ b/src/bloomish.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/cg3.h b/src/cg3.h
index aa8e336..9329ca6 100644
--- a/src/cg3.h
+++ b/src/cg3.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/cg_comp.cpp b/src/cg_comp.cpp
index 00fa650..e1c28b1 100644
--- a/src/cg_comp.cpp
+++ b/src/cg_comp.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2014, GrammarSoft ApS
+ * Copyright (C) 2007-2015, GrammarSoft ApS
  * Developed by Tino Didriksen <mail at tinodidriksen.com>
  * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
  *
@@ -98,7 +98,7 @@ int main(int argc, char *argv[]) {
 	grammar.reindex();
 
 	std::cerr << "Sections: " << grammar.sections.size() << ", Rules: " << grammar.rule_by_number.size();
-	std::cerr << ", Sets: " << grammar.sets_by_contents.size() << ", Tags: " << grammar.single_tags.size() << std::endl;
+	std::cerr << ", Sets: " << grammar.sets_list.size() << ", Tags: " << grammar.single_tags.size() << std::endl;
 
 	if (grammar.rules_any) {
 		std::cerr << grammar.rules_any->size() << " rules cannot be skipped by index." << std::endl;
diff --git a/src/cg_conv.cpp b/src/cg_conv.cpp
index 64b0340..0114cb6 100644
--- a/src/cg_conv.cpp
+++ b/src/cg_conv.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -100,6 +100,7 @@ int main(int argc, char *argv[]) {
 	CG3::Grammar grammar;
 
 	grammar.ux_stderr = ux_stderr;
+	grammar.allocateDummySet();
 	grammar.delimiters = grammar.allocateSet();
 	grammar.addTagToSet(grammar.allocateTag(CG3::stringbits[0].getTerminatedBuffer()), grammar.delimiters);
 	grammar.reindex();
diff --git a/src/cg_proc.cpp b/src/cg_proc.cpp
index b182506..1c8ec57 100644
--- a/src/cg_proc.cpp
+++ b/src/cg_proc.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/flat_unordered_map.hpp b/src/flat_unordered_map.hpp
index 7499179..34f505c 100644
--- a/src/flat_unordered_map.hpp
+++ b/src/flat_unordered_map.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -132,7 +132,7 @@ public:
 			reserve(std::max(static_cast<size_type>(DEFAULT_CAP), capacity() * 2));
 		}
 		size_t max = capacity() - 1;
-		size_t spot = t.first & max;
+		size_t spot = hash_value(t.first) & max;
 		while (elements[spot].first != res_empty) {
 			spot = (spot + 5) & max;
 		}
@@ -155,7 +155,7 @@ public:
 			return;
 		}
 		size_t max = capacity() - 1;
-		size_t spot = t & max;
+		size_t spot = hash_value(t) & max;
 		while (elements[spot].first != res_empty && elements[spot].first != t) {
 			spot = (spot + 5) & max;
 		}
@@ -179,7 +179,7 @@ public:
 
 		if (size_) {
 			size_t max = capacity() - 1;
-			size_t spot = t & max;
+			size_t spot = hash_value(t) & max;
 			while (elements[spot].first != res_empty && elements[spot].first != t) {
 				spot = (spot + 5) & max;
 			}
@@ -202,7 +202,7 @@ public:
 		size_t at = std::numeric_limits<size_t>::max();
 		if (size_) {
 			size_t max = capacity() - 1;
-			size_t spot = t & max;
+			size_t spot = hash_value(t) & max;
 			while (elements[spot].first != res_empty && elements[spot].first != t) {
 				spot = (spot + 5) & max;
 			}
@@ -259,7 +259,7 @@ public:
 		size_ = vals.size();
 		size_t max = capacity() - 1;
 		for (size_type i = 0, ie = vals.size(); i < ie; ++i) {
-			size_t spot = vals[i].first & max;
+			size_t spot = hash_value(vals[i].first) & max;
 			while (elements[spot].first != res_empty) {
 				spot = (spot + 5) & max;
 			}
@@ -297,6 +297,10 @@ private:
 	size_type size_;
 	container elements;
 
+	T hash_value(T t) const {
+		return (t << 8) | ((t >> 8) & 0xFF);
+	}
+
 	friend class const_iterator;
 };
 
diff --git a/src/flat_unordered_set.hpp b/src/flat_unordered_set.hpp
index d9b370d..bc08208 100644
--- a/src/flat_unordered_set.hpp
+++ b/src/flat_unordered_set.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -75,6 +75,12 @@ public:
 			return *this;
 		}
 
+		const_iterator operator++(int) {
+			const_iterator tmp(*this);
+			operator++();
+			return tmp;
+		}
+
 		const_iterator& operator--() {
 			if (i == 0) {
 				fus = 0;
@@ -124,7 +130,7 @@ public:
 			reserve(std::max(static_cast<size_type>(DEFAULT_CAP), capacity() * 2));
 		}
 		size_t max = capacity() - 1;
-		size_t spot = t & max;
+		size_t spot = hash_value(t) & max;
 		while (elements[spot] != res_empty) {
 			spot = (spot + 5) & max;
 		}
@@ -146,7 +152,7 @@ public:
 			return;
 		}
 		size_t max = capacity() - 1;
-		size_t spot = t & max;
+		size_t spot = hash_value(t) & max;
 		while (elements[spot] != res_empty && elements[spot] != t) {
 			spot = (spot + 5) & max;
 		}
@@ -168,7 +174,7 @@ public:
 
 		if (size_) {
 			size_t max = capacity() - 1;
-			size_t spot = t & max;
+			size_t spot = hash_value(t) & max;
 			while (elements[spot] != res_empty && elements[spot] != t) {
 				spot = (spot + 5) & max;
 			}
@@ -227,7 +233,7 @@ public:
 		size_ = vals.size();
 		size_t max = capacity() - 1;
 		for (size_type i = 0, ie = vals.size(); i < ie; ++i) {
-			size_t spot = vals[i] & max;
+			size_t spot = hash_value(vals[i]) & max;
 			while (elements[spot] != res_empty) {
 				spot = (spot + 5) & max;
 			}
@@ -265,6 +271,10 @@ private:
 	size_type size_;
 	container elements;
 
+	T hash_value(T t) const {
+		return (t << 8) | ((t >> 8) & 0xFF);
+	}
+
 	friend class const_iterator;
 };
 
diff --git a/src/inlines.hpp b/src/inlines.hpp
index 81208cd..3d09171 100644
--- a/src/inlines.hpp
+++ b/src/inlines.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -89,7 +89,7 @@ inline uint32_t SuperFastHash(const char *data, size_t len = 0, uint32_t hash =
 	hash ^= hash << 25;
 	hash += hash >> 6;
 
-	if (hash == 0 || hash == 1) {
+	if (hash == 0 || hash == std::numeric_limits<uint32_t>::max() || hash == std::numeric_limits<uint32_t>::max()-1) {
 		hash = CG3_HASH_SEED;
 	}
 
@@ -135,7 +135,7 @@ inline uint32_t SuperFastHash(const UChar *data, size_t len = 0, uint32_t hash =
 	hash ^= hash << 25;
 	hash += hash >> 6;
 
-	if (hash == 0 || hash == 1) {
+	if (hash == 0 || hash == std::numeric_limits<uint32_t>::max() || hash == std::numeric_limits<uint32_t>::max()-1) {
 		hash = CG3_HASH_SEED;
 	}
 
@@ -172,7 +172,7 @@ inline uint32_t hash_value(uint32_t c, uint32_t h = CG3_HASH_SEED) {
 	}
 	//*
 	h = c + (h << 6U) + (h << 16U) - h;
-	if (h == 0 || h == 1) {
+	if (h == 0 || h == std::numeric_limits<uint32_t>::max() || h == std::numeric_limits<uint32_t>::max()-1) {
 		h = CG3_HASH_SEED;
 	}
 	return h;
diff --git a/src/interval_vector.hpp b/src/interval_vector.hpp
index 8de7eea..bb53c8b 100644
--- a/src/interval_vector.hpp
+++ b/src/interval_vector.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -193,6 +193,13 @@ public:
 		return true;
 	}
 
+	template<typename It>
+	void insert(It b, It e) {
+		for (; b != e; ++b) {
+			insert(*b);
+		}
+	}
+
 	bool push_back(T t) {
 		return insert(t);
 	}
diff --git a/src/istream.hpp b/src/istream.hpp
index 3d1ad26..1f6eecc 100644
--- a/src/istream.hpp
+++ b/src/istream.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/libcg3.cpp b/src/libcg3.cpp
index 55085ca..21006ec 100644
--- a/src/libcg3.cpp
+++ b/src/libcg3.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/macros.hpp b/src/macros.hpp
index 6a7dc88..bfca73c 100644
--- a/src/macros.hpp
+++ b/src/macros.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/main.cpp b/src/main.cpp
index c1cb0ca..2b9359c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -282,7 +282,7 @@ int main(int argc, char* argv[]) {
 	main_timer = clock();
 
 	if (options[VERBOSE].doesOccur) {
-		std::cerr << "Grammar has " << grammar.sections.size() << " sections, " << grammar.template_list.size() << " templates, " << grammar.rule_by_number.size() << " rules, " << grammar.sets_list.size() << " sets, " << grammar.single_tags.size() << " tags." << std::endl;
+		std::cerr << "Grammar has " << grammar.sections.size() << " sections, " << grammar.templates.size() << " templates, " << grammar.rule_by_number.size() << " rules, " << grammar.sets_list.size() << " sets, " << grammar.single_tags.size() << " tags." << std::endl;
 		if (grammar.rules_any) {
 			std::cerr << grammar.rules_any->size() << " rules cannot be skipped by index." << std::endl;
 		}
@@ -353,7 +353,7 @@ int main(int argc, char* argv[]) {
 		}
 		std::cerr << "Optimizer removed " << bad.size() << " rules." << std::endl;
 		grammar.reindex();
-		std::cerr << "Grammar has " << grammar.sections.size() << " sections, " << grammar.template_list.size() << " templates, " << grammar.rule_by_number.size() << " rules, " << grammar.sets_list.size() << " sets, " << grammar.single_tags.size() << " tags." << std::endl;
+		std::cerr << "Grammar has " << grammar.sections.size() << " sections, " << grammar.templates.size() << " templates, " << grammar.rule_by_number.size() << " rules, " << grammar.sets_list.size() << " sets, " << grammar.single_tags.size() << " tags." << std::endl;
 	}
 	if (options[OPTIMIZE_SAFE].doesOccur) {
 		CG3::RuleVector bad;
@@ -371,7 +371,7 @@ int main(int argc, char* argv[]) {
 		}
 		std::cerr << "Optimizer moved " << bad.size() << " rules." << std::endl;
 		grammar.reindex();
-		std::cerr << "Grammar has " << grammar.sections.size() << " sections, " << grammar.template_list.size() << " templates, " << grammar.rule_by_number.size() << " rules, " << grammar.sets_list.size() << " sets, " << grammar.single_tags.size() << " tags." << std::endl;
+		std::cerr << "Grammar has " << grammar.sections.size() << " sections, " << grammar.templates.size() << " templates, " << grammar.rule_by_number.size() << " rules, " << grammar.sets_list.size() << " sets, " << grammar.single_tags.size() << " tags." << std::endl;
 	}
 
 	if (options[GRAMMAR_OUT].doesOccur) {
diff --git a/src/options.hpp b/src/options.hpp
index c4625a1..ca31c5b 100644
--- a/src/options.hpp
+++ b/src/options.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/options_conv.hpp b/src/options_conv.hpp
index d649a7b..1e74213 100644
--- a/src/options_conv.hpp
+++ b/src/options_conv.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/sorted_vector.hpp b/src/sorted_vector.hpp
index 27e3d3f..efa41db 100644
--- a/src/sorted_vector.hpp
+++ b/src/sorted_vector.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -29,6 +29,20 @@
 #include <stdint.h> // C99 or C++0x or C++ TR1 will have this header. ToDo: Change to <cstdint> when C++0x broader support gets under way.
 
 namespace CG3 {
+	namespace detail {
+		template<typename ForwardIt, typename Comp>
+		bool is_sorted(ForwardIt first, ForwardIt last, Comp comp) {
+			if (first != last) {
+				ForwardIt next = first;
+				while (++next != last) {
+					if (comp(*next, *first))
+						return false;
+					first = next;
+				}
+			}
+			return true;
+		}
+	}
 
 template<typename T, typename Comp = std::less<T> >
 class sorted_vector {
@@ -77,9 +91,29 @@ public:
 
 	template<typename It>
 	void insert(It b, It e) {
-		for (; b != e ; ++b) {
+		size_t d = std::distance(b, e);
+		if (d == 1) {
 			insert(*b);
+			return;
+		}
+
+		static container merged;
+		merged.resize(0);
+		merged.reserve(elements.size() + d);
+
+		if (detail::is_sorted(b, e, comp)) {
+			std::merge(elements.begin(), elements.end(), b, e, std::back_inserter(merged), comp);
 		}
+		else {
+			static container sorted;
+			sorted.assign(b, e);
+			std::sort(sorted.begin(), sorted.end(), comp);
+			std::merge(elements.begin(), elements.end(), sorted.begin(), sorted.end(), std::back_inserter(merged), comp);
+		}
+
+		merged.swap(elements);
+		iterator it = std::unique(elements.begin(), elements.end());
+		elements.erase(it, elements.end());
 	}
 
 	bool push_back(T t) {
diff --git a/src/stdafx.hpp b/src/stdafx.hpp
index 72e5b9d..9ffab55 100644
--- a/src/stdafx.hpp
+++ b/src/stdafx.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -85,9 +85,6 @@
 #define boost_reverse_foreach BOOST_REVERSE_FOREACH
 #define stdext boost
 #define hash_map unordered_map
-#define hash_set unordered_set
-#define hash_multimap unordered_multimap
-#define hash_multiset unordered_multiset
 
 #ifdef _MSC_VER
 	#include <winsock.h> // for hton() and family.
@@ -115,8 +112,6 @@ namespace CG3 {
 	typedef std::basic_string<UChar> UString;
 	typedef std::vector<UString> UStringVector;
 	typedef std::vector<uint32_t> uint32Vector;
-	typedef std::map<uint32_t,int32_t> uint32int32Map;
-	typedef std::map<uint32_t,uint32_t> uint32Map;
 	namespace bc = ::boost::container;
 }
 
diff --git a/src/test_libcg3.c b/src/test_libcg3.c
index cc98a0b..2b9b569 100644
--- a/src/test_libcg3.c
+++ b/src/test_libcg3.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/uextras.cpp b/src/uextras.cpp
index 9f4265a..4ba9172 100644
--- a/src/uextras.cpp
+++ b/src/uextras.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/uextras.hpp b/src/uextras.hpp
index 29b9be2..617378c 100644
--- a/src/uextras.hpp
+++ b/src/uextras.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
diff --git a/src/version.hpp b/src/version.hpp
index bf5c14f..2abdb47 100644
--- a/src/version.hpp
+++ b/src/version.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2007-2014, GrammarSoft ApS
+* Copyright (C) 2007-2015, GrammarSoft ApS
 * Developed by Tino Didriksen <mail at tinodidriksen.com>
 * Design by Eckhard Bick <eckhard.bick at mail.dk>, Tino Didriksen <mail at tinodidriksen.com>
 *
@@ -25,14 +25,14 @@
 
 #include <stdint.h>
 
-const char* const CG3_COPYRIGHT_STRING = "Copyright (C) 2007-2014 GrammarSoft ApS. Licensed under GPLv3+";
+const char* const CG3_COPYRIGHT_STRING = "Copyright (C) 2007-2015 GrammarSoft ApS. Licensed under GPLv3+";
 
 const uint32_t CG3_VERSION_MAJOR = 0;
 const uint32_t CG3_VERSION_MINOR = 9;
 const uint32_t CG3_VERSION_PATCH = 9;
-const uint32_t CG3_REVISION = 10195;
-const uint32_t CG3_FEATURE_REV = 10043;
-const uint32_t CG3_TOO_OLD = 10043;
+const uint32_t CG3_REVISION = 10379;
+const uint32_t CG3_FEATURE_REV = 10373;
+const uint32_t CG3_TOO_OLD = 10373;
 const uint32_t CG3_EXTERNAL_PROTOCOL = 7226;
 
 #endif
diff --git a/test/T_AnyMinusSome/args.txt b/test/T_AnyMinusSome/args.txt
new file mode 100755
index 0000000..d5e9673
--- /dev/null
+++ b/test/T_AnyMinusSome/args.txt
@@ -0,0 +1 @@
+--unique-tags
\ No newline at end of file
diff --git a/test/T_AnyMinusSome/grammar.cg3b.10043 b/test/T_AnyMinusSome/grammar.cg3b.10043
new file mode 100644
index 0000000..de8d547
Binary files /dev/null and b/test/T_AnyMinusSome/grammar.cg3b.10043 differ
diff --git a/test/T_AnyMinusSome/run.pl b/test/T_AnyMinusSome/run.pl
deleted file mode 100755
index cacfbe7..0000000
--- a/test/T_AnyMinusSome/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3 --unique-tags -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3b --unique-tags -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Barrier/grammar.cg3b.10043 b/test/T_Barrier/grammar.cg3b.10043
new file mode 100644
index 0000000..48bcb44
Binary files /dev/null and b/test/T_Barrier/grammar.cg3b.10043 differ
diff --git a/test/T_Barrier/run.pl b/test/T_Barrier/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_Barrier/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_BasicAppend/grammar.cg3b.10043 b/test/T_BasicAppend/grammar.cg3b.10043
new file mode 100644
index 0000000..85acd67
Binary files /dev/null and b/test/T_BasicAppend/grammar.cg3b.10043 differ
diff --git a/test/T_BasicAppend/run.pl b/test/T_BasicAppend/run.pl
deleted file mode 100755
index 9e695d0..0000000
--- a/test/T_BasicAppend/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_BasicContextTest/grammar.cg3b.10043 b/test/T_BasicContextTest/grammar.cg3b.10043
new file mode 100644
index 0000000..5c5e5a4
Binary files /dev/null and b/test/T_BasicContextTest/grammar.cg3b.10043 differ
diff --git a/test/T_BasicContextTest/run.pl b/test/T_BasicContextTest/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_BasicContextTest/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_BasicDelimit/args.txt b/test/T_BasicDelimit/args.txt
new file mode 100755
index 0000000..45ede5c
--- /dev/null
+++ b/test/T_BasicDelimit/args.txt
@@ -0,0 +1 @@
+-e
\ No newline at end of file
diff --git a/test/T_BasicDelimit/expected.txt b/test/T_BasicDelimit/expected.txt
index 2be7608..c56c256 100644
--- a/test/T_BasicDelimit/expected.txt
+++ b/test/T_BasicDelimit/expected.txt
@@ -2,11 +2,11 @@
 	"word" notwanted
 	"word" notmeeither
 "<word>"
-	"word" notwanted
-	"matchme" wanted
-	"word" notmeeither
+	"word" notwanted <<<
+	"matchme" wanted <<<
+	"word" notmeeither <<<
 
 "<word>"
-	"word" notwanted
-	"word" notmeeither
+	"word" notwanted <<<
+	"word" notmeeither <<<
 
diff --git a/test/T_BasicDelimit/grammar.cg3b.10043 b/test/T_BasicDelimit/grammar.cg3b.10043
new file mode 100644
index 0000000..55f4a49
Binary files /dev/null and b/test/T_BasicDelimit/grammar.cg3b.10043 differ
diff --git a/test/T_BasicDelimit/run.pl b/test/T_BasicDelimit/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_BasicDelimit/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_BasicDependency/args.txt b/test/T_BasicDependency/args.txt
new file mode 100755
index 0000000..67f25c8
--- /dev/null
+++ b/test/T_BasicDependency/args.txt
@@ -0,0 +1 @@
+--unicode-tags -D
\ No newline at end of file
diff --git a/test/T_BasicDependency/grammar.cg3b.10043 b/test/T_BasicDependency/grammar.cg3b.10043
new file mode 100644
index 0000000..99b4fa6
Binary files /dev/null and b/test/T_BasicDependency/grammar.cg3b.10043 differ
diff --git a/test/T_BasicDependency/run.pl b/test/T_BasicDependency/run.pl
deleted file mode 100755
index e534d4d..0000000
--- a/test/T_BasicDependency/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --unicode-tags -D --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --unicode-tags -D --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C UTF-8 --unicode-tags -D --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_BasicIff/grammar.cg3b.10043 b/test/T_BasicIff/grammar.cg3b.10043
new file mode 100644
index 0000000..38b7425
Binary files /dev/null and b/test/T_BasicIff/grammar.cg3b.10043 differ
diff --git a/test/T_BasicIff/run.pl b/test/T_BasicIff/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_BasicIff/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_BasicSelect/args.txt b/test/T_BasicSelect/args.txt
new file mode 100755
index 0000000..45ede5c
--- /dev/null
+++ b/test/T_BasicSelect/args.txt
@@ -0,0 +1 @@
+-e
\ No newline at end of file
diff --git a/test/T_BasicSelect/grammar.cg3b.10043 b/test/T_BasicSelect/grammar.cg3b.10043
new file mode 100644
index 0000000..503ae42
Binary files /dev/null and b/test/T_BasicSelect/grammar.cg3b.10043 differ
diff --git a/test/T_BasicSelect/run.pl b/test/T_BasicSelect/run.pl
deleted file mode 100755
index 9cc4e3c..0000000
--- a/test/T_BasicSelect/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -e -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -e -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -e -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_BasicSubstitute/args.txt b/test/T_BasicSubstitute/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_BasicSubstitute/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_BasicSubstitute/grammar.cg3b.10043 b/test/T_BasicSubstitute/grammar.cg3b.10043
new file mode 100644
index 0000000..ae64209
Binary files /dev/null and b/test/T_BasicSubstitute/grammar.cg3b.10043 differ
diff --git a/test/T_BasicSubstitute/run.pl b/test/T_BasicSubstitute/run.pl
deleted file mode 100755
index 2bdbdd9..0000000
--- a/test/T_BasicSubstitute/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -t -C UTF-8 -g grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -b -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -t -C UTF-8 -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -t -C UTF-8 -g grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -b -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_CG2Compat/args.txt b/test/T_CG2Compat/args.txt
new file mode 100755
index 0000000..6869d7c
--- /dev/null
+++ b/test/T_CG2Compat/args.txt
@@ -0,0 +1 @@
+--ordered --vislcg-compat
\ No newline at end of file
diff --git a/test/T_CG2Compat/grammar.cg3b.10043 b/test/T_CG2Compat/grammar.cg3b.10043
new file mode 100644
index 0000000..f1b286d
Binary files /dev/null and b/test/T_CG2Compat/grammar.cg3b.10043 differ
diff --git a/test/T_CG2Compat/run.pl b/test/T_CG2Compat/run.pl
deleted file mode 100755
index e93315a..0000000
--- a/test/T_CG2Compat/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --ordered --vislcg-compat -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] --ordered --vislcg-compat -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --ordered --vislcg-compat -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_CarefulBarrier/grammar.cg3b.10043 b/test/T_CarefulBarrier/grammar.cg3b.10043
new file mode 100644
index 0000000..d03f338
Binary files /dev/null and b/test/T_CarefulBarrier/grammar.cg3b.10043 differ
diff --git a/test/T_CarefulBarrier/run.pl b/test/T_CarefulBarrier/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_CarefulBarrier/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_DelayAndDelete/grammar.cg3b.10043 b/test/T_DelayAndDelete/grammar.cg3b.10043
new file mode 100644
index 0000000..011d304
Binary files /dev/null and b/test/T_DelayAndDelete/grammar.cg3b.10043 differ
diff --git a/test/T_DelayAndDelete/run.pl b/test/T_DelayAndDelete/run.pl
deleted file mode 100755
index 47dba4d..0000000
--- a/test/T_DelayAndDelete/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -g grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -g grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Dependency_Loops/args.txt b/test/T_Dependency_Loops/args.txt
new file mode 100755
index 0000000..15aa799
--- /dev/null
+++ b/test/T_Dependency_Loops/args.txt
@@ -0,0 +1 @@
+--dep-no-crossing
\ No newline at end of file
diff --git a/test/T_Dependency_Loops/grammar.cg3b.10043 b/test/T_Dependency_Loops/grammar.cg3b.10043
new file mode 100644
index 0000000..71bf659
Binary files /dev/null and b/test/T_Dependency_Loops/grammar.cg3b.10043 differ
diff --git a/test/T_Dependency_Loops/run.pl b/test/T_Dependency_Loops/run.pl
deleted file mode 100755
index 1135a0b..0000000
--- a/test/T_Dependency_Loops/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --dep-no-crossing -v -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] --dep-no-crossing -v -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --dep-no-crossing -v -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Dependency_OutOfRange/expected.txt b/test/T_Dependency_OutOfRange/expected.txt
index b635107..42fb9b7 100644
--- a/test/T_Dependency_OutOfRange/expected.txt
+++ b/test/T_Dependency_OutOfRange/expected.txt
@@ -7,7 +7,7 @@
 "<a>"
 	"o" <artd> <-sam> DET F S @>N #4->4
 "<mulher>"
-	"mulher" <Hattr> N F S @P< �PAT #5->3
+	"mulher" <Hattr> N F S @P< §PAT #5->3
 "<$.>"
 	"$." PU @PU #6->0
 </s>
diff --git a/test/T_Dependency_OutOfRange/grammar.cg3 b/test/T_Dependency_OutOfRange/grammar.cg3
index d2a7c58..ae0d602 100644
--- a/test/T_Dependency_OutOfRange/grammar.cg3
+++ b/test/T_Dependency_OutOfRange/grammar.cg3
@@ -1,6 +1,6 @@
 DELIMITERS = "<$.>" ;
 
-MAPPING-PREFIX = � ;
+MAPPING-PREFIX = § ;
 
 LIST @ACC = @<ACC @ACC> ;
 LIST @PIV = @<PIV @PIV> ;
@@ -8,6 +8,6 @@ LIST @P< = @P< ;
 LIST N-ANIM = <H> <Hfam> <Hprof> <Hattr> <A> ;
 LIST PRP = PRP ;
 
-MAP (�DES) TARGET @P< (*-1 PRP LINK 0 ("em") LINK 0 @PIV LINK p ("bater")) (NOT 0 N-ANIM) ;
-MAP (�PAT) TARGET @P< (*-1 PRP LINK 0 ("em") LINK p ("bater") LINK NONE c @ACC) ;
-MAP (�PAT �EXP) TARGET @ACC (p ("bater")) ;
+MAP (§DES) TARGET @P< (*-1 PRP LINK 0 ("em") LINK 0 @PIV LINK p ("bater")) (NOT 0 N-ANIM) ;
+MAP (§PAT) TARGET @P< (*-1 PRP LINK 0 ("em") LINK p ("bater") LINK NONE c @ACC) ;
+MAP (§PAT §EXP) TARGET @ACC (p ("bater")) ;
diff --git a/test/T_Dependency_OutOfRange/grammar.cg3b.10043 b/test/T_Dependency_OutOfRange/grammar.cg3b.10043
new file mode 100644
index 0000000..84a6764
Binary files /dev/null and b/test/T_Dependency_OutOfRange/grammar.cg3b.10043 differ
diff --git a/test/T_Dependency_OutOfRange/run.pl b/test/T_Dependency_OutOfRange/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_Dependency_OutOfRange/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_DontMatchEmptySet/grammar.cg3b.10043 b/test/T_DontMatchEmptySet/grammar.cg3b.10043
new file mode 100644
index 0000000..f691675
Binary files /dev/null and b/test/T_DontMatchEmptySet/grammar.cg3b.10043 differ
diff --git a/test/T_DontMatchEmptySet/run.pl b/test/T_DontMatchEmptySet/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_DontMatchEmptySet/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_EndlessSelect/grammar.cg3b.10043 b/test/T_EndlessSelect/grammar.cg3b.10043
new file mode 100644
index 0000000..b9242ce
Binary files /dev/null and b/test/T_EndlessSelect/grammar.cg3b.10043 differ
diff --git a/test/T_EndlessSelect/run.pl b/test/T_EndlessSelect/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_EndlessSelect/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_External/grammar.cg3b.10043 b/test/T_External/grammar.cg3b.10043
new file mode 100644
index 0000000..14aeed6
Binary files /dev/null and b/test/T_External/grammar.cg3b.10043 differ
diff --git a/test/T_Include/grammar.cg3b.10043 b/test/T_Include/grammar.cg3b.10043
new file mode 100644
index 0000000..0ab4134
Binary files /dev/null and b/test/T_Include/grammar.cg3b.10043 differ
diff --git a/test/T_Include/run.pl b/test/T_Include/run.pl
deleted file mode 100755
index 78357e2..0000000
--- a/test/T_Include/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -b -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -b -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_InputCommands/grammar.cg3b.10043 b/test/T_InputCommands/grammar.cg3b.10043
new file mode 100644
index 0000000..9940699
Binary files /dev/null and b/test/T_InputCommands/grammar.cg3b.10043 differ
diff --git a/test/T_InputCommands/run.pl b/test/T_InputCommands/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_InputCommands/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_InputMarkup/grammar.cg3b.10043 b/test/T_InputMarkup/grammar.cg3b.10043
new file mode 100644
index 0000000..17e888b
Binary files /dev/null and b/test/T_InputMarkup/grammar.cg3b.10043 differ
diff --git a/test/T_InputMarkup/run.pl b/test/T_InputMarkup/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_InputMarkup/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_JumpExecute/args.txt b/test/T_JumpExecute/args.txt
new file mode 100755
index 0000000..45ede5c
--- /dev/null
+++ b/test/T_JumpExecute/args.txt
@@ -0,0 +1 @@
+-e
\ No newline at end of file
diff --git a/test/T_JumpExecute/grammar.cg3b.10043 b/test/T_JumpExecute/grammar.cg3b.10043
new file mode 100644
index 0000000..3fbca4a
Binary files /dev/null and b/test/T_JumpExecute/grammar.cg3b.10043 differ
diff --git a/test/T_JumpExecute/run.pl b/test/T_JumpExecute/run.pl
deleted file mode 100755
index 9cc4e3c..0000000
--- a/test/T_JumpExecute/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -e -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -e -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -e -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_MapAdd_Different/args.txt b/test/T_MapAdd_Different/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_MapAdd_Different/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_MapAdd_Different/expected.txt b/test/T_MapAdd_Different/expected.txt
index 98236ef..ddbdc17 100644
--- a/test/T_MapAdd_Different/expected.txt
+++ b/test/T_MapAdd_Different/expected.txt
@@ -1,5 +1,5 @@
 "<word>"
 	"word" notwanted
-	"matchme" wanted $tag �tag @tag @mapped ADD:8 ADD:9 ADD:10 MAP:12
+	"matchme" wanted $tag £tag @tag @mapped ADD:8 ADD:9 ADD:10 MAP:12
 	"word" notmeeither
 
diff --git a/test/T_MapAdd_Different/grammar.cg3 b/test/T_MapAdd_Different/grammar.cg3
index 7371544..79b57d1 100644
--- a/test/T_MapAdd_Different/grammar.cg3
+++ b/test/T_MapAdd_Different/grammar.cg3
@@ -6,7 +6,7 @@ LIST ASet = ".atc[hm]{2}.*"r ;
 SECTION
 
 ADD ($tag) ASet ;
-ADD (�tag) ASet ;
+ADD (£tag) ASet ;
 ADD (@tag) ASet ;
 
-MAP (@mapped) (�tag) ;
+MAP (@mapped) (£tag) ;
diff --git a/test/T_MapAdd_Different/grammar.cg3b.10043 b/test/T_MapAdd_Different/grammar.cg3b.10043
new file mode 100644
index 0000000..4efa53a
Binary files /dev/null and b/test/T_MapAdd_Different/grammar.cg3b.10043 differ
diff --git a/test/T_MapAdd_Different/run.pl b/test/T_MapAdd_Different/run.pl
deleted file mode 100755
index ac08102..0000000
--- a/test/T_MapAdd_Different/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_MapThenRemove/grammar.cg3b.10043 b/test/T_MapThenRemove/grammar.cg3b.10043
new file mode 100644
index 0000000..19b499f
Binary files /dev/null and b/test/T_MapThenRemove/grammar.cg3b.10043 differ
diff --git a/test/T_MapThenRemove/run.pl b/test/T_MapThenRemove/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_MapThenRemove/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_MapThenSelect/grammar.cg3b.10043 b/test/T_MapThenSelect/grammar.cg3b.10043
new file mode 100644
index 0000000..aae3148
Binary files /dev/null and b/test/T_MapThenSelect/grammar.cg3b.10043 differ
diff --git a/test/T_MapThenSelect/run.pl b/test/T_MapThenSelect/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_MapThenSelect/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_MappingPrefix/args.txt b/test/T_MappingPrefix/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_MappingPrefix/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_MappingPrefix/grammar.cg3b.10043 b/test/T_MappingPrefix/grammar.cg3b.10043
new file mode 100644
index 0000000..fcafe70
Binary files /dev/null and b/test/T_MappingPrefix/grammar.cg3b.10043 differ
diff --git a/test/T_MappingPrefix/run.pl b/test/T_MappingPrefix/run.pl
deleted file mode 100755
index 8f738c5..0000000
--- a/test/T_MappingPrefix/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --trace -C UTF-8 -g grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] --trace -C UTF-8 -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --trace -C UTF-8 -g grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Movement/grammar.cg3b.10043 b/test/T_Movement/grammar.cg3b.10043
new file mode 100644
index 0000000..d533bf0
Binary files /dev/null and b/test/T_Movement/grammar.cg3b.10043 differ
diff --git a/test/T_Movement/run.pl b/test/T_Movement/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_Movement/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_MultipleSections/grammar.cg3b.10043 b/test/T_MultipleSections/grammar.cg3b.10043
new file mode 100644
index 0000000..de0e199
Binary files /dev/null and b/test/T_MultipleSections/grammar.cg3b.10043 differ
diff --git a/test/T_MultipleSections/run.pl b/test/T_MultipleSections/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_MultipleSections/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_NegatedContextTest/grammar.cg3b.10043 b/test/T_NegatedContextTest/grammar.cg3b.10043
new file mode 100644
index 0000000..be0cefc
Binary files /dev/null and b/test/T_NegatedContextTest/grammar.cg3b.10043 differ
diff --git a/test/T_NegatedContextTest/run.pl b/test/T_NegatedContextTest/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_NegatedContextTest/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_NotContextTest/grammar.cg3b.10043 b/test/T_NotContextTest/grammar.cg3b.10043
new file mode 100644
index 0000000..066fddc
Binary files /dev/null and b/test/T_NotContextTest/grammar.cg3b.10043 differ
diff --git a/test/T_NotContextTest/run.pl b/test/T_NotContextTest/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_NotContextTest/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_NumericalTags/args.txt b/test/T_NumericalTags/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_NumericalTags/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_NumericalTags/grammar.cg3b.10043 b/test/T_NumericalTags/grammar.cg3b.10043
new file mode 100644
index 0000000..967fab7
Binary files /dev/null and b/test/T_NumericalTags/grammar.cg3b.10043 differ
diff --git a/test/T_NumericalTags/run.pl b/test/T_NumericalTags/run.pl
deleted file mode 100755
index a5c26e3..0000000
--- a/test/T_NumericalTags/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --trace --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --trace --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_OmniWithBarrier/grammar.cg3b.10043 b/test/T_OmniWithBarrier/grammar.cg3b.10043
new file mode 100644
index 0000000..5823b07
Binary files /dev/null and b/test/T_OmniWithBarrier/grammar.cg3b.10043 differ
diff --git a/test/T_OmniWithBarrier/run.pl b/test/T_OmniWithBarrier/run.pl
deleted file mode 100755
index 3d3afa2..0000000
--- a/test/T_OmniWithBarrier/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Omniscan/grammar.cg3b.10043 b/test/T_Omniscan/grammar.cg3b.10043
new file mode 100644
index 0000000..b3ed49e
Binary files /dev/null and b/test/T_Omniscan/grammar.cg3b.10043 differ
diff --git a/test/T_Omniscan/run.pl b/test/T_Omniscan/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_Omniscan/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_OriginPassing/args.txt b/test/T_OriginPassing/args.txt
new file mode 100755
index 0000000..09fbc50
--- /dev/null
+++ b/test/T_OriginPassing/args.txt
@@ -0,0 +1 @@
+--no-pass-origin
\ No newline at end of file
diff --git a/test/T_OriginPassing/grammar.cg3b.10043 b/test/T_OriginPassing/grammar.cg3b.10043
new file mode 100644
index 0000000..cf76368
Binary files /dev/null and b/test/T_OriginPassing/grammar.cg3b.10043 differ
diff --git a/test/T_OriginPassing/run.pl b/test/T_OriginPassing/run.pl
deleted file mode 100755
index f666858..0000000
--- a/test/T_OriginPassing/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --no-pass-origin -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --no-pass-origin -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Parentheses/args.txt b/test/T_Parentheses/args.txt
new file mode 100755
index 0000000..ed0ea2a
--- /dev/null
+++ b/test/T_Parentheses/args.txt
@@ -0,0 +1 @@
+--trace-encl
\ No newline at end of file
diff --git a/test/T_Parentheses/grammar.cg3b.10043 b/test/T_Parentheses/grammar.cg3b.10043
new file mode 100644
index 0000000..fc6f67c
Binary files /dev/null and b/test/T_Parentheses/grammar.cg3b.10043 differ
diff --git a/test/T_Parentheses/run.pl b/test/T_Parentheses/run.pl
deleted file mode 100755
index d24e9b1..0000000
--- a/test/T_Parentheses/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --trace-encl -C UTF-8 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] --trace-encl -C UTF-8 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --trace-encl -C UTF-8 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_RegExp/grammar.cg3b.10043 b/test/T_RegExp/grammar.cg3b.10043
new file mode 100644
index 0000000..0dc8b37
Binary files /dev/null and b/test/T_RegExp/grammar.cg3b.10043 differ
diff --git a/test/T_RegExp/run.pl b/test/T_RegExp/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_RegExp/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Relations/args.txt b/test/T_Relations/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_Relations/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_Relations/grammar.cg3b.10043 b/test/T_Relations/grammar.cg3b.10043
new file mode 100644
index 0000000..c4b44d2
Binary files /dev/null and b/test/T_Relations/grammar.cg3b.10043 differ
diff --git a/test/T_Relations/run.pl b/test/T_Relations/run.pl
deleted file mode 100755
index 1fabd87..0000000
--- a/test/T_Relations/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3 --trace -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C UTF-8 -g grammar.cg3b --trace -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_RemCohort/args.txt b/test/T_RemCohort/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_RemCohort/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_RemCohort/grammar.cg3b.10043 b/test/T_RemCohort/grammar.cg3b.10043
new file mode 100644
index 0000000..f02d4c4
Binary files /dev/null and b/test/T_RemCohort/grammar.cg3b.10043 differ
diff --git a/test/T_RemCohort/run.pl b/test/T_RemCohort/run.pl
deleted file mode 100755
index 3b23a33..0000000
--- a/test/T_RemCohort/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -t -C UTF-8 -g grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -t -C UTF-8 -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -t -C UTF-8 -g grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_RemoveSingleTag/grammar.cg3b.10043 b/test/T_RemoveSingleTag/grammar.cg3b.10043
new file mode 100644
index 0000000..9c462d7
Binary files /dev/null and b/test/T_RemoveSingleTag/grammar.cg3b.10043 differ
diff --git a/test/T_RemoveSingleTag/run.pl b/test/T_RemoveSingleTag/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_RemoveSingleTag/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_ScanningTests/grammar.cg3b.10043 b/test/T_ScanningTests/grammar.cg3b.10043
new file mode 100644
index 0000000..0ccda9e
Binary files /dev/null and b/test/T_ScanningTests/grammar.cg3b.10043 differ
diff --git a/test/T_ScanningTests/run.pl b/test/T_ScanningTests/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_ScanningTests/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_SectionRanges/args.txt b/test/T_SectionRanges/args.txt
new file mode 100755
index 0000000..fa2e028
--- /dev/null
+++ b/test/T_SectionRanges/args.txt
@@ -0,0 +1 @@
+--sections 1,4-6,3
\ No newline at end of file
diff --git a/test/T_SectionRanges/grammar.cg3b.10043 b/test/T_SectionRanges/grammar.cg3b.10043
new file mode 100644
index 0000000..713e08c
Binary files /dev/null and b/test/T_SectionRanges/grammar.cg3b.10043 differ
diff --git a/test/T_SectionRanges/run.pl b/test/T_SectionRanges/run.pl
deleted file mode 100755
index c71582e..0000000
--- a/test/T_SectionRanges/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --sections 1,4-6,3 -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --sections 1,4-6,3 -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Sections/args.txt b/test/T_Sections/args.txt
new file mode 100755
index 0000000..333f4cc
--- /dev/null
+++ b/test/T_Sections/args.txt
@@ -0,0 +1 @@
+--sections 4
\ No newline at end of file
diff --git a/test/T_Sections/grammar.cg3b.10043 b/test/T_Sections/grammar.cg3b.10043
new file mode 100644
index 0000000..06b1800
Binary files /dev/null and b/test/T_Sections/grammar.cg3b.10043 differ
diff --git a/test/T_Sections/run.pl b/test/T_Sections/run.pl
deleted file mode 100755
index d4cf32d..0000000
--- a/test/T_Sections/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --sections 4 -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --sections 4 -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_SetOp_FailFast/args.txt b/test/T_SetOp_FailFast/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_SetOp_FailFast/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_SetOp_FailFast/grammar.cg3b.10043 b/test/T_SetOp_FailFast/grammar.cg3b.10043
new file mode 100644
index 0000000..009ce4b
Binary files /dev/null and b/test/T_SetOp_FailFast/grammar.cg3b.10043 differ
diff --git a/test/T_SetOp_FailFast/run.pl b/test/T_SetOp_FailFast/run.pl
deleted file mode 100755
index d11de27..0000000
--- a/test/T_SetOp_FailFast/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_SetOps/grammar.cg3b.10043 b/test/T_SetOps/grammar.cg3b.10043
new file mode 100644
index 0000000..27ed3dc
Binary files /dev/null and b/test/T_SetOps/grammar.cg3b.10043 differ
diff --git a/test/T_SetOps/run.pl b/test/T_SetOps/run.pl
deleted file mode 100755
index 3d3afa2..0000000
--- a/test/T_SetOps/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_SetParentChild/grammar.cg3b.10043 b/test/T_SetParentChild/grammar.cg3b.10043
new file mode 100644
index 0000000..e6ace4b
Binary files /dev/null and b/test/T_SetParentChild/grammar.cg3b.10043 differ
diff --git a/test/T_SetParentChild/run.pl b/test/T_SetParentChild/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_SetParentChild/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_SoftDelimiters/args.txt b/test/T_SoftDelimiters/args.txt
new file mode 100755
index 0000000..ea81bb1
--- /dev/null
+++ b/test/T_SoftDelimiters/args.txt
@@ -0,0 +1 @@
+--soft-limit 4 --hard-limit 6
\ No newline at end of file
diff --git a/test/T_SoftDelimiters/grammar.cg3b.10043 b/test/T_SoftDelimiters/grammar.cg3b.10043
new file mode 100644
index 0000000..93d9237
Binary files /dev/null and b/test/T_SoftDelimiters/grammar.cg3b.10043 differ
diff --git a/test/T_SoftDelimiters/run.pl b/test/T_SoftDelimiters/run.pl
deleted file mode 100755
index 39849f5..0000000
--- a/test/T_SoftDelimiters/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -v --soft-limit 4 --hard-limit 6 -C UTF-8 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -v -C UTF-8 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -v --soft-limit 4 --hard-limit 6 -C UTF-8 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_SpaceInForms/args.txt b/test/T_SpaceInForms/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_SpaceInForms/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_SpaceInForms/grammar.cg3b.10043 b/test/T_SpaceInForms/grammar.cg3b.10043
new file mode 100644
index 0000000..3db25bc
Binary files /dev/null and b/test/T_SpaceInForms/grammar.cg3b.10043 differ
diff --git a/test/T_SpaceInForms/run.pl b/test/T_SpaceInForms/run.pl
deleted file mode 100755
index d11de27..0000000
--- a/test/T_SpaceInForms/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_SubReadings_Apertium/grammar.cg3b.10043 b/test/T_SubReadings_Apertium/grammar.cg3b.10043
new file mode 100644
index 0000000..0d6fa2a
Binary files /dev/null and b/test/T_SubReadings_Apertium/grammar.cg3b.10043 differ
diff --git a/test/T_SubReadings_CG/args.txt b/test/T_SubReadings_CG/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_SubReadings_CG/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_SubReadings_CG/grammar.cg3b.10043 b/test/T_SubReadings_CG/grammar.cg3b.10043
new file mode 100644
index 0000000..2d3f0d1
Binary files /dev/null and b/test/T_SubReadings_CG/grammar.cg3b.10043 differ
diff --git a/test/T_SubReadings_CG/run.pl b/test/T_SubReadings_CG/run.pl
deleted file mode 100755
index d9eb731..0000000
--- a/test/T_SubReadings_CG/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --trace -C UTF-8 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C UTF-8 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --trace -C UTF-8 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_SubstituteNil/grammar.cg3b.10043 b/test/T_SubstituteNil/grammar.cg3b.10043
new file mode 100644
index 0000000..59c82d1
Binary files /dev/null and b/test/T_SubstituteNil/grammar.cg3b.10043 differ
diff --git a/test/T_SubstituteNil/run.pl b/test/T_SubstituteNil/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_SubstituteNil/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Templates/grammar.cg3b.10043 b/test/T_Templates/grammar.cg3b.10043
new file mode 100644
index 0000000..674d062
Binary files /dev/null and b/test/T_Templates/grammar.cg3b.10043 differ
diff --git a/test/T_Templates/run.pl b/test/T_Templates/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_Templates/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Trace/args.txt b/test/T_Trace/args.txt
new file mode 100755
index 0000000..1db23ad
--- /dev/null
+++ b/test/T_Trace/args.txt
@@ -0,0 +1 @@
+-t
\ No newline at end of file
diff --git a/test/T_Trace/grammar.cg3b.10043 b/test/T_Trace/grammar.cg3b.10043
new file mode 100644
index 0000000..af195b7
Binary files /dev/null and b/test/T_Trace/grammar.cg3b.10043 differ
diff --git a/test/T_Trace/run.pl b/test/T_Trace/run.pl
deleted file mode 100755
index d11de27..0000000
--- a/test/T_Trace/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] --trace -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Unification/args.txt b/test/T_Unification/args.txt
new file mode 100755
index 0000000..15f41d5
--- /dev/null
+++ b/test/T_Unification/args.txt
@@ -0,0 +1 @@
+--trace-name-only
\ No newline at end of file
diff --git a/test/T_Unification/grammar.cg3b.10043 b/test/T_Unification/grammar.cg3b.10043
new file mode 100644
index 0000000..0f85ca4
Binary files /dev/null and b/test/T_Unification/grammar.cg3b.10043 differ
diff --git a/test/T_Unification/run.pl b/test/T_Unification/run.pl
deleted file mode 100755
index ae9e004..0000000
--- a/test/T_Unification/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -v9 --trace-name-only -C UTF-8 -g grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -v9 --trace-name-only -C UTF-8 -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -v9 --trace-name-only -C UTF-8 -g grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/T_Variables/grammar.cg3b.10043 b/test/T_Variables/grammar.cg3b.10043
new file mode 100644
index 0000000..072b6fb
Binary files /dev/null and b/test/T_Variables/grammar.cg3b.10043 differ
diff --git a/test/T_Variables/run.pl b/test/T_Variables/run.pl
deleted file mode 100755
index be6d200..0000000
--- a/test/T_Variables/run.pl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd qw(realpath);
-
-my ($bindir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
-$bindir = realpath $bindir;
-chdir $bindir or die("Error: Could not change directory to $bindir !");
-
-my $binary = $ARGV[0];
-if (!$binary || $binary eq '' || !(-x $binary)) {
-	die("Error: $binary is not executable!");
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
-`diff -B expected.txt output.txt >diff.txt`;
-
-if (-s "diff.txt") {
-	print STDERR "Fail ";
-} else {
-	print STDERR "Success ";
-}
-
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
-`"$binary" $ARGV[1] -C ISO-8859-1 --grammar grammar.cg3b -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
-`diff -B expected.txt output.bin.txt >diff.bin.txt`;
-
-if (-s "diff.bin.txt") {
-	print STDERR "Fail.\n";
-} else {
-	print STDERR "Success.\n";
-}
diff --git a/test/runall.pl b/test/runall.pl
index 222bb86..1ab0912 100755
--- a/test/runall.pl
+++ b/test/runall.pl
@@ -21,9 +21,46 @@ my @binlist = (
 	"../Release/vislcg3",
 	"../src/vislcg3",
 	"../vislcg3",
-);
+	);
+my @unlinks = (
+   'diff.txt',
+   'output.txt',
+   'grammar.cg3b',
+   'diff.bin.txt',
+   'output.bin.txt',
+   );
 my $binary = "vislcg3";
 
+sub run_pl {
+   my ($binary,$override,$args) = @_;
+
+   `"$binary" $args $override -g grammar.cg3 -I input.txt -O output.txt >stdout.txt 2>stderr.txt`;
+   `diff -B expected.txt output.txt >diff.txt`;
+
+   if (-s "diff.txt") {
+      print STDERR "Fail ";
+   } else {
+      print STDERR "Success ";
+   }
+
+   `"$binary" $args $override -g grammar.cg3 --grammar-only --grammar-bin grammar.cg3b >stdout.bin.txt 2>stderr.bin.txt`;
+   my $gf = undef;
+   for my $g (glob('*.cg3b*')) {
+      `"$binary" $args $override -g '$g' -I input.txt -O output.bin.txt >>stdout.bin.txt 2>>stderr.bin.txt`;
+      `diff -B expected.txt output.bin.txt >diff.bin.txt`;
+      if (-s "diff.bin.txt") {
+         $gf = $g;
+         last;
+      }
+   }
+
+   if (-s "diff.bin.txt") {
+      print STDERR "Fail ($gf).\n";
+   } else {
+      print STDERR "Success.\n";
+   }
+}
+
 foreach (@binlist) {
 	if (-x $_) {
 		$binary = $_;
@@ -47,13 +84,14 @@ print STDERR "Binary found at: $binary\n";
 
 print STDERR "\nRunning tests...\n";
 
-my @tests = grep { -x } glob('./T*/run.pl');
+my @tests = grep { -x } glob('./T_*');
 foreach (@tests) {
 	if ($ARGV[0] && $ARGV[0] ne "" && !(/$ARGV[0]/i)) {
 		next;
 	}
 	chdir $bindir or die("Error: Could not change directory to $bindir !");
 	my ($test) = m/^.*?(T[^\/]+).*$/;
+	chdir $test or die("Error: Could not change directory to $test !");
 	print STDERR "$test: ";
 	for (my $i=length $test;$i<30;$i++) {
 		print STDERR " ";
@@ -61,26 +99,26 @@ foreach (@tests) {
 	if (-s "./$test/byline.txt") {
 		print STDERR "(".`cat "./$test/byline.txt"`.") ";
 	}
-	if (-e "./".$test."/diff.txt") {
-	    unlink "./".$test."/diff.txt";
-	}
-	if (-e "./".$test."/output.txt") {
-	    unlink "./".$test."/output.txt";
-	}
-	if (-e "./".$test."/grammar.cg3b") {
-	    unlink "./".$test."/grammar.cg3b";
-	}
-	if (-e "./".$test."/diff.bin.txt") {
-	    unlink "./".$test."/diff.bin.txt";
-	}
-	if (-e "./".$test."/output.bin.txt") {
-	    unlink "./".$test."/output.bin.txt";
+	for my $u (@unlinks) {
+	   if (-e $u) {
+	      unlink $u;
+	   }
 	}
+
 	my $c = '""';
 	if ($ARGV[1] && $ARGV[1] ne "") {
 		$c = '"'.$ARGV[1].'"';
 	}
-	`$_ "$binary" \Q$c\E`;
+	my $args = '';
+	if (-s 'args.txt') {
+	   $args = `cat args.txt`;
+	}
+	if (-x 'run.pl') {
+	   `./run.pl "$binary" \Q$c\E $args`;
+	}
+	else {
+	   run_pl($binary, $c, $args);
+	}
 }
 
 print STDERR "\n";
diff --git a/vapply.sh b/vapply.sh
index e190bdb..5569894 100755
--- a/vapply.sh
+++ b/vapply.sh
@@ -8,7 +8,7 @@ mkdir -p vapply
 cd vapply
 rm -fv callgrind.*
 mv -vf annotated annotated.old
-g++ -std=c++$CXXV -DNDEBUG -pipe -Wall -Wextra -Wno-deprecated -O3 -g3 -L/usr/local/lib64 -L/usr/local/lib -licuio -licuuc -I../include -I../include/exec-stream ../src/all_vislcg3.cpp -o vislcg3-c++$CXXV.debug
+g++ -std=c++$CXXV -DNDEBUG -pthread -pipe -Wall -Wextra -Wno-deprecated -O3 -g3 -I../include -I../include/exec-stream ../src/all_vislcg3.cpp -o vislcg3-c++$CXXV.debug -L/usr/lib/x86_64-linux-gnu -licui18n -licudata -licuio -licuuc
 head -n 2000 ../comparison/arboretum_stripped.txt | valgrind --tool=callgrind --compress-strings=no --compress-pos=no --collect-jumps=yes --collect-systime=yes ./vislcg3-c++$CXXV.debug -v -C UTF-8 -g ../dancg.cg3b > output.txt
 #head -n 2000 ../comparison/arboretum_stripped.txt | valgrind ./vislcg3-c++$CXXV.debug -v -C UTF-8 -g ../dancg.cg3b > output.txt
 callgrind_annotate --tree=both --auto=yes > annotated
diff --git a/vparse.sh b/vparse.sh
index 308bb86..395e808 100755
--- a/vparse.sh
+++ b/vparse.sh
@@ -6,6 +6,6 @@ mkdir -p vparse
 cd vparse
 rm -f callgrind.*
 mv -vf annotated annotated.old
-g++ -std=c++$CXXV -DNDEBUG -Wall -Wextra -Wno-deprecated -pipe -O3 -g3 -L/usr/local/lib64 -L/usr/local/lib -licuio -licuuc -I../include -I../include/exec-stream ../src/all_vislcg3.cpp -o vislcg3-c++$CXXV.debug
+g++ -std=c++$CXXV -DNDEBUG -Wall -Wextra -Wno-deprecated -pthread -pipe -O3 -g3 -I../include -I../include/exec-stream ../src/all_vislcg3.cpp -o vislcg3-c++$CXXV.debug -L/usr/lib/x86_64-linux-gnu -licui18n -licudata -licuio -licuuc
 valgrind --tool=callgrind --compress-strings=no --compress-pos=no --collect-jumps=yes --collect-systime=yes ./vislcg3-c++$CXXV.debug -C UTF-8 --grammar-only -g ~/parsers/dansk/etc/dancg
 callgrind_annotate --tree=both --auto=yes > annotated

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



More information about the debian-science-commits mailing list