Merged trunk.
diff --git a/bootstrap_test.go b/bootstrap_test.go
index de93b6d..e50d9ea 100644
--- a/bootstrap_test.go
+++ b/bootstrap_test.go
@@ -13,9 +13,9 @@
 package gocheck_test
 
 import (
+	"fmt"
 	"launchpad.net/gocheck"
 	"strings"
-	"fmt"
 )
 
 type BootstrapS struct{}
diff --git a/checkers.go b/checkers.go
index e6e72c4..5c91200 100644
--- a/checkers.go
+++ b/checkers.go
@@ -1,9 +1,9 @@
 package gocheck
 
 import (
+	"fmt"
 	"reflect"
 	"regexp"
-	"fmt"
 )
 
 // -----------------------------------------------------------------------
@@ -238,7 +238,6 @@
 	return value.Len() == n, ""
 }
 
-
 // -----------------------------------------------------------------------
 // ErrorMatches checker.
 
diff --git a/foundation_test.go b/foundation_test.go
index d59b99e..9f89150 100644
--- a/foundation_test.go
+++ b/foundation_test.go
@@ -7,12 +7,12 @@
 package gocheck_test
 
 import (
-	"launchpad.net/gocheck"
-	"strings"
-	"regexp"
 	"fmt"
+	"launchpad.net/gocheck"
 	"log"
 	"os"
+	"regexp"
+	"strings"
 )
 
 // -----------------------------------------------------------------------
diff --git a/gocheck.go b/gocheck.go
index e26e7cb..c353b3e 100644
--- a/gocheck.go
+++ b/gocheck.go
@@ -53,6 +53,24 @@
 	return method.Info.Func.Pointer()
 }
 
+func (method *methodType) suiteName() string {
+	t := method.Info.Type.In(0)
+	if t.Kind() == reflect.Ptr {
+		t = t.Elem()
+	}
+	return t.Name()
+}
+
+func (method *methodType) String() string {
+	return method.suiteName()+"."+method.Info.Name
+}
+
+func (method *methodType) matches(re *regexp.Regexp) bool {
+	return (re.MatchString(method.Info.Name) ||
+		re.MatchString(method.suiteName()) ||
+		re.MatchString(method.String()))
+}
+
 type C struct {
 	method   *methodType
 	kind     funcKind
@@ -504,24 +522,8 @@
 		}
 	}
 
-	// This map will be used to filter out duplicated methods.  This
-	// looks like a bug in Go, described on issue 906:
-	// http://code.google.com/p/go/issues/detail?id=906
-	seen := make(map[uintptr]bool, suiteNumMethods)
-
-	// XXX Shouldn't Name() work here? Why does it return an empty string?
-	suiteName := suiteType.String()
-	if index := strings.LastIndex(suiteName, "."); index != -1 {
-		suiteName = suiteName[index+1:]
-	}
-
 	for i := 0; i != suiteNumMethods; i++ {
 		method := newMethod(suiteValue, i)
-		methodPC := method.PC()
-		if _, found := seen[methodPC]; found {
-			continue
-		}
-		seen[methodPC] = true
 		switch method.Info.Name {
 		case "SetUpSuite":
 			runner.setUpSuite = method
@@ -532,7 +534,14 @@
 		case "TearDownTest":
 			runner.tearDownTest = method
 		default:
-			if isWanted(conf.Benchmark, suiteName, method.Info.Name, filterRegexp) {
+			prefix := "Test"
+			if conf.Benchmark {
+				prefix = "Benchmark"
+			}
+			if !strings.HasPrefix(method.Info.Name, prefix) {
+				continue
+			}
+			if filterRegexp == nil || method.matches(filterRegexp) {
 				runner.tests = append(runner.tests, method)
 			}
 		}
@@ -540,25 +549,6 @@
 	return runner
 }
 
-// isWanted returns true if the given suite and method names should be run.
-// The bench result indicates whether the method is a benchmark rather than
-// a test.
-func isWanted(benchmark bool, suiteName, methodName string, filterRegexp *regexp.Regexp) bool {
-	prefix := "Test"
-	if benchmark {
-		prefix = "Benchmark"
-	}
-	if !strings.HasPrefix(methodName, prefix) {
-		return false
-	}
-	if filterRegexp == nil {
-		return true
-	}
-	return (filterRegexp.MatchString(methodName) ||
-		filterRegexp.MatchString(suiteName) ||
-		filterRegexp.MatchString(suiteName+"."+methodName))
-}
-
 // Run all methods in the given suite.
 func (runner *suiteRunner) run() *Result {
 	if runner.tracker.result.RunError == nil && len(runner.tests) > 0 {
diff --git a/gocheck_test.go b/gocheck_test.go
index e4bf4d4..aad261a 100644
--- a/gocheck_test.go
+++ b/gocheck_test.go
@@ -4,13 +4,13 @@
 package gocheck_test
 
 import (
-	"launchpad.net/gocheck"
-	"testing"
-	"runtime"
-	"regexp"
 	"flag"
 	"fmt"
+	"launchpad.net/gocheck"
 	"os"
+	"regexp"
+	"runtime"
+	"testing"
 	"time"
 )
 
diff --git a/helpers_test.go b/helpers_test.go
index 0469426..79348bc 100644
--- a/helpers_test.go
+++ b/helpers_test.go
@@ -126,7 +126,7 @@
 	testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
 		func() interface{} {
 			// Nice leading comment.
-			return c.Check(1, checker, 2)  // Hello there
+			return c.Check(1, checker, 2) // Hello there
 		})
 }
 
@@ -379,7 +379,6 @@
 		})
 }
 
-
 // -----------------------------------------------------------------------
 // MakeDir() tests.
 
diff --git a/run.go b/run.go
index 6d6393c..dc75d77 100644
--- a/run.go
+++ b/run.go
@@ -1,8 +1,10 @@
 package gocheck
 
 import (
+	"bufio"
 	"flag"
 	"fmt"
+	"os"
 	"testing"
 	"time"
 )
@@ -24,11 +26,12 @@
 // Public running interface.
 
 var (
-	filterFlag  = flag.String("gocheck.f", "", "Regular expression selecting what to run")
+	filterFlag  = flag.String("gocheck.f", "", "Regular expression selecting which tests and/or suites to run")
 	verboseFlag = flag.Bool("gocheck.v", false, "Verbose mode")
 	streamFlag  = flag.Bool("gocheck.vv", false, "Super verbose mode (disables output caching)")
 	benchFlag   = flag.Bool("gocheck.b", false, "Run benchmarks")
 	benchTime   = flag.Duration("gocheck.btime", 1 * time.Second, "approximate run time for each benchmark")
+	listFlag    = flag.Bool("gocheck.list", false, "List the names of all tests that will be run")
 )
 
 // Run all test suites registered with the Suite() function, printing
@@ -42,6 +45,14 @@
 		Benchmark: *benchFlag,
 		BenchmarkTime: *benchTime,
 	}
+	if *listFlag {
+		w := bufio.NewWriter(os.Stdout)
+		for _, name := range ListAll(conf) {
+			fmt.Fprintln(w, name)
+		}
+		w.Flush()
+		return
+	}
 	result := RunAll(conf)
 	println(result.String())
 	if !result.Passed() {
@@ -49,7 +60,7 @@
 	}
 }
 
-// Run all test suites registered with the Suite() function, using the
+// RunAll runs all test suites registered with the Suite() function, using the
 // given run configuration.
 func RunAll(runConf *RunConf) *Result {
 	result := Result{}
@@ -59,12 +70,34 @@
 	return &result
 }
 
-// Run the given test suite using the provided run configuration.
+// Run runs the given test suite using the provided run configuration.
 func Run(suite interface{}, runConf *RunConf) *Result {
 	runner := newSuiteRunner(suite, runConf)
 	return runner.run()
 }
 
+// ListAll returns the names of all the test functions registered with the
+// Suite function that will be run with the provided run configuration.
+func ListAll(runConf *RunConf) []string {
+	var names []string
+	for _, suite := range allSuites {
+		names = append(names, List(suite, runConf)...)
+	}
+	return names
+}
+
+// List prints the names of the test functions in the given
+// suite that will be run with the provided run configuration
+// to the given Writer.
+func List(suite interface{}, runConf *RunConf) []string {
+	var names []string
+	runner := newSuiteRunner(suite, runConf)
+	for _, t := range runner.tests {
+		names = append(names, t.String())
+	}
+	return names
+}
+
 // -----------------------------------------------------------------------
 // Result methods.
 
diff --git a/run_test.go b/run_test.go
index 081d3af..3700ac7 100644
--- a/run_test.go
+++ b/run_test.go
@@ -2,6 +2,7 @@
 
 package gocheck_test
 
+
 import (
 	"errors"
 	. "launchpad.net/gocheck"
@@ -99,21 +100,21 @@
 
 func (s *RunS) TestAdd(c *C) {
 	result := &Result{
-		Succeeded: 1,
-		Skipped: 2,
-		Failed: 3,
-		Panicked: 4,
-		FixturePanicked: 5,
-		Missed: 6,
+		Succeeded:        1,
+		Skipped:          2,
+		Failed:           3,
+		Panicked:         4,
+		FixturePanicked:  5,
+		Missed:           6,
 		ExpectedFailures: 7,
 	}
 	result.Add(&Result{
-		Succeeded: 10,
-		Skipped: 20,
-		Failed: 30,
-		Panicked: 40,
-		FixturePanicked: 50,
-		Missed: 60,
+		Succeeded:        10,
+		Skipped:          20,
+		Failed:           30,
+		Panicked:         40,
+		FixturePanicked:  50,
+		Missed:           60,
 		ExpectedFailures: 70,
 	})
 	c.Check(result.Succeeded, Equals, 11)
@@ -280,6 +281,24 @@
 }
 
 // -----------------------------------------------------------------------
+// Verify that List works correctly.
+
+func (s *RunS) TestListFiltered(c *C) {
+	names := List(&FixtureHelper{}, &RunConf{Filter: "1"})
+	c.Assert(names, DeepEquals, []string{
+		"FixtureHelper.Test1",
+	})
+}
+
+func (s *RunS) TestList(c *C) {
+	names := List(&FixtureHelper{}, &RunConf{})
+	c.Assert(names, DeepEquals, []string{
+		"FixtureHelper.Test1",
+		"FixtureHelper.Test2",
+	})
+}
+
+// -----------------------------------------------------------------------
 // Verify that verbose mode prints tests which pass as well. 
 
 func (s *RunS) TestVerboseMode(c *C) {