First cut of -c/—section option for running specific sections
diff --git a/include/internal/catch_commandline.hpp b/include/internal/catch_commandline.hpp
index 89eced3..adee52b 100644
--- a/include/internal/catch_commandline.hpp
+++ b/include/internal/catch_commandline.hpp
@@ -23,6 +23,7 @@
         config.abortAfter = x;
     }
     inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
+    inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); }
     inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
 
     inline void addWarning( ConfigData& config, std::string const& _warning ) {
@@ -176,6 +177,10 @@
             .describe( "adds a tag for the filename" )
             .bind( &ConfigData::filenamesAsTags );
 
+        cli["-c"]["--section"]
+                .describe( "specify section to run" )
+                .bind( &addSectionToRun, "section name" );
+
         // Less common commands which don't have a short form
         cli["--list-test-names-only"]
             .describe( "list all/matching test cases names only" )
diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp
index 72b0f6c..7d7887a 100644
--- a/include/internal/catch_config.hpp
+++ b/include/internal/catch_config.hpp
@@ -74,6 +74,7 @@
 
         std::vector<std::string> reporterNames;
         std::vector<std::string> testsOrTags;
+        std::vector<std::string> sectionsToRun;
     };
 
 
@@ -115,7 +116,8 @@
 
         bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
 
-        std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
+        std::vector<std::string> const& getReporterNames() const { return m_data.reporterNames; }
+        std::vector<std::string> const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; }
 
         int abortAfter() const { return m_data.abortAfter; }
 
diff --git a/include/internal/catch_interfaces_config.h b/include/internal/catch_interfaces_config.h
index 17914b4..768550b 100644
--- a/include/internal/catch_interfaces_config.h
+++ b/include/internal/catch_interfaces_config.h
@@ -62,6 +62,8 @@
         virtual RunTests::InWhatOrder runOrder() const = 0;
         virtual unsigned int rngSeed() const = 0;
         virtual UseColour::YesOrNo useColour() const = 0;
+        virtual std::vector<std::string> const& getSectionsToRun() const = 0;
+
     };
 }
 
diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp
index d37bdba..e458afc 100644
--- a/include/internal/catch_run_context.hpp
+++ b/include/internal/catch_run_context.hpp
@@ -97,10 +97,11 @@
 
 
             do {
-                m_trackerContext.startRun();
+                ITracker& rootTracker = m_trackerContext.startRun();
+                dynamic_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
                 do {
                     m_trackerContext.startCycle();
-                    m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
+                    m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) );
                     runCurrentTest( redirectedCout, redirectedCerr );
                 }
                 while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
@@ -155,10 +156,7 @@
             Counts& assertions
         )
         {
-            std::ostringstream oss;
-            oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
-
-            ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
+            ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) );
             if( !sectionTracker.isOpen() )
                 return false;
             m_activeSections.push_back( &sectionTracker );
diff --git a/include/internal/catch_test_case_tracker.hpp b/include/internal/catch_test_case_tracker.hpp
index 3973e7b..d2b14a2 100644
--- a/include/internal/catch_test_case_tracker.hpp
+++ b/include/internal/catch_test_case_tracker.hpp
@@ -19,11 +19,21 @@
 namespace Catch {
 namespace TestCaseTracking {
 
+    struct NameAndLocation {
+        std::string name;
+        SourceLineInfo location;
+
+        NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
+        :   name( _name ),
+            location( _location )
+        {}
+    };
+
     struct ITracker : SharedImpl<> {
         virtual ~ITracker();
 
         // static queries
-        virtual std::string name() const = 0;
+        virtual NameAndLocation const& nameAndLocation() const = 0;
 
         // dynamic queries
         virtual bool isComplete() const = 0; // Successfully completed or failed
@@ -39,7 +49,7 @@
         virtual void markAsNeedingAnotherRun() = 0;
 
         virtual void addChild( Ptr<ITracker> const& child ) = 0;
-        virtual ITracker* findChild( std::string const& name ) = 0;
+        virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0;
         virtual void openChild() = 0;
         
         // Debug/ checking
@@ -47,7 +57,7 @@
         virtual bool isIndexTracker() const = 0;
     };
 
-    class TrackerContext {
+    class  TrackerContext {
 
         enum RunState {
             NotStarted,
@@ -110,30 +120,32 @@
             Failed
         };
         class TrackerHasName {
-            std::string m_name;
+            NameAndLocation m_nameAndLocation;
         public:
-            TrackerHasName( std::string const& name ) : m_name( name ) {}
+            TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
             bool operator ()( Ptr<ITracker> const& tracker ) {
-                return tracker->name() == m_name;
+                return
+                    tracker->nameAndLocation().name == m_nameAndLocation.name &&
+                    tracker->nameAndLocation().location == m_nameAndLocation.location;
             }
         };
         typedef std::vector<Ptr<ITracker> > Children;
-        std::string m_name;
+        NameAndLocation m_nameAndLocation;
         TrackerContext& m_ctx;
         ITracker* m_parent;
         Children m_children;
         CycleState m_runState;
     public:
-        TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
-        :   m_name( name ),
+        TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+        :   m_nameAndLocation( nameAndLocation ),
             m_ctx( ctx ),
             m_parent( parent ),
             m_runState( NotStarted )
         {}
         virtual ~TrackerBase();
 
-        virtual std::string name() const CATCH_OVERRIDE {
-            return m_name;
+        virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE {
+            return m_nameAndLocation;
         }
         virtual bool isComplete() const CATCH_OVERRIDE {
             return m_runState == CompletedSuccessfully || m_runState == Failed;
@@ -153,8 +165,8 @@
             m_children.push_back( child );
         }
 
-        virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
-            Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
+        virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE {
+            Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
             return( it != m_children.end() )
                 ? it->get()
                 : CATCH_NULL;
@@ -232,41 +244,65 @@
     };
 
     class SectionTracker : public TrackerBase {
+        std::vector<std::string> m_filters;
     public:
-        SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
-        :   TrackerBase( name, ctx, parent )
-        {}
+        SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+        :   TrackerBase( nameAndLocation, ctx, parent )
+        {
+            if( parent ) {
+                while( !parent->isSectionTracker() )
+                    parent = &parent->parent();
+
+                SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
+                addNextFilters( parentSection.m_filters );
+            }
+        }
         virtual ~SectionTracker();
 
         virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
         
-        static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
+        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
             SectionTracker* section = CATCH_NULL;
 
             ITracker& currentTracker = ctx.currentTracker();
-            if( ITracker* childTracker = currentTracker.findChild( name ) ) {
+            if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
                 assert( childTracker );
                 assert( childTracker->isSectionTracker() );
                 section = static_cast<SectionTracker*>( childTracker );
             }
             else {
-                section = new SectionTracker( name, ctx, &currentTracker );
+                section = new SectionTracker( nameAndLocation, ctx, &currentTracker );
                 currentTracker.addChild( section );
             }
-            if( !ctx.completedCycle() && !section->isComplete() ) {
-
-                section->open();
-            }
+            if( !ctx.completedCycle() )
+                section->tryOpen();
             return *section;
         }
+
+        void tryOpen() {
+            if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
+                open();
+        }
+
+        void addInitialFilters( std::vector<std::string> const& filters ) {
+            if( !filters.empty() ) {
+                m_filters.push_back(""); // Root - should never be consulted
+                m_filters.push_back(""); // Test Case - not a section filter
+                std::copy( filters.begin(), filters.end(), std::back_inserter( m_filters ) );
+            }
+        }
+        void addNextFilters( std::vector<std::string> const& filters ) {
+            if( filters.size() > 1 )
+                std::copy( filters.begin()+1, filters.end(), std::back_inserter( m_filters ) );
+        }
     };
 
     class IndexTracker : public TrackerBase {
         int m_size;
         int m_index;
     public:
-        IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
-        :   TrackerBase( name, ctx, parent ),
+        IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
+        :   TrackerBase( nameAndLocation, ctx, parent ),
             m_size( size ),
             m_index( -1 )
         {}
@@ -274,17 +310,17 @@
 
         virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
         
-        static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
+        static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
             IndexTracker* tracker = CATCH_NULL;
 
             ITracker& currentTracker = ctx.currentTracker();
-            if( ITracker* childTracker = currentTracker.findChild( name ) ) {
+            if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
                 assert( childTracker );
                 assert( childTracker->isIndexTracker() );
                 tracker = static_cast<IndexTracker*>( childTracker );
             }
             else {
-                tracker = new IndexTracker( name, ctx, &currentTracker, size );
+                tracker = new IndexTracker( nameAndLocation, ctx, &currentTracker, size );
                 currentTracker.addChild( tracker );
             }
 
@@ -312,7 +348,7 @@
     };
 
     inline ITracker& TrackerContext::startRun() {
-        m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
+        m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL );
         m_currentTracker = CATCH_NULL;
         m_runState = Executing;
         return *m_rootTracker;
diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp
index 2925635..45f4cf1 100644
--- a/projects/SelfTest/PartTrackerTests.cpp
+++ b/projects/SelfTest/PartTrackerTests.cpp
@@ -36,16 +36,21 @@
 //    REQUIRE( C_A_T_C_H_Context().i() == 42 );
 //}
 
+Catch::TestCaseTracking::NameAndLocation makeNAL( std::string const& name ) {
+    return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo() );
+}
+
 TEST_CASE( "Tracker", "" ) {
 
     TrackerContext ctx;
     ctx.startRun();
     ctx.startCycle();
 
-    ITracker& testCase = SectionTracker::acquire( ctx, "Testcase" );
+
+    ITracker& testCase = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
     REQUIRE( testCase.isOpen() );
 
-    ITracker& s1 = SectionTracker::acquire( ctx, "S1" );
+    ITracker& s1 = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
     REQUIRE( s1.isOpen() );
 
     SECTION( "successfully close one section", "" ) {
@@ -70,10 +75,10 @@
 
         SECTION( "re-enter after failed section", "" ) {
             ctx.startCycle();
-            ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+            ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
             REQUIRE( testCase2.isOpen() );
 
-            ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+            ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
             REQUIRE( s1b.isOpen() == false );
 
             testCase2.close();
@@ -83,13 +88,13 @@
         }
         SECTION( "re-enter after failed section and find next section", "" ) {
             ctx.startCycle();
-            ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+            ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
             REQUIRE( testCase2.isOpen() );
 
-            ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+            ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
             REQUIRE( s1b.isOpen() == false );
 
-            ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+            ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
             REQUIRE( s2.isOpen() );
 
             s2.close();
@@ -104,7 +109,7 @@
     SECTION( "successfully close one section, then find another", "" ) {
         s1.close();
 
-        ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+        ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
         REQUIRE( s2.isOpen() == false );
 
         testCase.close();
@@ -112,13 +117,13 @@
 
         SECTION( "Re-enter - skips S1 and enters S2", "" ) {
             ctx.startCycle();
-            ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+            ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
             REQUIRE( testCase2.isOpen() );
 
-            ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+            ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
             REQUIRE( s1b.isOpen() == false );
 
-            ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
+            ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
             REQUIRE( s2b.isOpen() );
 
             REQUIRE( ctx.completedCycle() == false );
@@ -145,13 +150,13 @@
 
                 // Need a final cycle
                 ctx.startCycle();
-                ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" );
+                ITracker& testCase3 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
                 REQUIRE( testCase3.isOpen() );
 
-                ITracker& s1c = SectionTracker::acquire( ctx, "S1" );
+                ITracker& s1c = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
                 REQUIRE( s1c.isOpen() == false );
 
-                ITracker& s2c = SectionTracker::acquire( ctx, "S2" );
+                ITracker& s2c = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
                 REQUIRE( s2c.isOpen() == false );
 
                 testCase3.close();
@@ -161,7 +166,7 @@
     }
 
     SECTION( "open a nested section", "" ) {
-        ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+        ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
         REQUIRE( s2.isOpen() );
 
         s2.close();
@@ -177,7 +182,7 @@
     }
 
     SECTION( "start a generator", "" ) {
-        IndexTracker& g1 = IndexTracker::acquire( ctx, "G1", 2 );
+        IndexTracker& g1 = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
         REQUIRE( g1.isOpen() );
         REQUIRE( g1.index() == 0 );
 
@@ -193,14 +198,14 @@
 
             SECTION( "Re-enter for second generation", "" ) {
                 ctx.startCycle();
-                ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+                ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
                 REQUIRE( testCase2.isOpen() );
 
-                ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+                ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
                 REQUIRE( s1b.isOpen() );
 
 
-                IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
+                IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
                 REQUIRE( g1b.isOpen() );
                 REQUIRE( g1b.index() == 1 );
 
@@ -214,7 +219,7 @@
             }
         }
         SECTION( "Start a new inner section", "" ) {
-            ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+            ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
             REQUIRE( s2.isOpen() );
 
             s2.close();
@@ -228,19 +233,19 @@
 
             SECTION( "Re-enter for second generation", "" ) {
                 ctx.startCycle();
-                ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+                ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
                 REQUIRE( testCase2.isOpen() );
 
-                ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+                ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
                 REQUIRE( s1b.isOpen() );
 
                 // generator - next value
-                IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
+                IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
                 REQUIRE( g1b.isOpen() );
                 REQUIRE( g1b.index() == 1 );
 
                 // inner section again
-                ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
+                ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
                 REQUIRE( s2b.isOpen() );
 
                 s2b.close();
@@ -256,7 +261,7 @@
         }
 
         SECTION( "Fail an inner section", "" ) {
-            ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+            ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
             REQUIRE( s2.isOpen() );
 
             s2.fail();
@@ -271,19 +276,19 @@
 
             SECTION( "Re-enter for second generation", "" ) {
                 ctx.startCycle();
-                ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+                ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
                 REQUIRE( testCase2.isOpen() );
 
-                ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+                ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
                 REQUIRE( s1b.isOpen() );
 
                 // generator - still same value
-                IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
+                IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
                 REQUIRE( g1b.isOpen() );
                 REQUIRE( g1b.index() == 0 );
 
                 // inner section again - this time won't open
-                ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
+                ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
                 REQUIRE( s2b.isOpen() == false );
 
                 s1b.close();
@@ -295,19 +300,19 @@
 
                 // Another cycle - now should complete
                 ctx.startCycle();
-                ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" );
+                ITracker& testCase3 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
                 REQUIRE( testCase3.isOpen() );
 
-                ITracker& s1c = SectionTracker::acquire( ctx, "S1" );
+                ITracker& s1c = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
                 REQUIRE( s1c.isOpen() );
 
                 // generator - now next value
-                IndexTracker& g1c = IndexTracker::acquire( ctx, "G1", 2 );
+                IndexTracker& g1c = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
                 REQUIRE( g1c.isOpen() );
                 REQUIRE( g1c.index() == 1 );
 
                 // inner section - now should open again
-                ITracker& s2c = SectionTracker::acquire( ctx, "S2" );
+                ITracker& s2c = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
                 REQUIRE( s2c.isOpen() );
 
                 s2c.close();