diff --git a/.gitignore b/.gitignore
index 61ead86..7b26c94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 /vendor
+/coverage.txt
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..fbb4374
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,15 @@
+language: go
+
+go:
+  - 1.8.x
+  - 1.x
+
+before_install:
+  - go get -t -v ./...
+  - go get -t -v github.com/modern-go/reflect2-tests/...
+
+script:
+  - ./test.sh
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/Gopkg.toml b/Gopkg.toml
index 3593fd0..2f4f4db 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -24,7 +24,7 @@
 #   go-tests = true
 #   unused-packages = true
 
-ignored = ["github.com/modern-go/test","github.com/modern-go/test/must","github.com/modern-go/test/should"]
+ignored = []
 
 [[constraint]]
   name = "github.com/modern-go/concurrent"
diff --git a/README.md b/README.md
index 6b429ef..6f968aa 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,71 @@
 # reflect2
+
+[![Sourcegraph](https://sourcegraph.com/github.com/modern-go/reflect2/-/badge.svg)](https://sourcegraph.com/github.com/modern-go/reflect2?badge)
+[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/modern-go/reflect2)
+[![Build Status](https://travis-ci.org/modern-go/reflect2.svg?branch=master)](https://travis-ci.org/modern-go/reflect2)
+[![codecov](https://codecov.io/gh/modern-go/reflect2/branch/master/graph/badge.svg)](https://codecov.io/gh/modern-go/reflect2)
+[![rcard](https://goreportcard.com/badge/github.com/modern-go/reflect2)](https://goreportcard.com/report/github.com/modern-go/reflect2)
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/reflect2/master/LICENSE)
+
 reflect api that avoids runtime reflect.Value cost
+
+* reflect get/set interface{}, with type checking
+* reflect get/set unsafe.Pointer, without type checking
+* `reflect2.TypeByName` works like `Class.forName` found in java
+
+[json-iterator](https://github.com/json-iterator/go) use this package to save runtime dispatching cost.
+This package is designed for low level libraries to optimize reflection performance.
+General application should still use reflect standard library.
+
+# reflect2.TypeByName
+
+```go
+// given package is github.com/your/awesome-package
+type MyStruct struct {
+	// ...
+}
+
+// will return the type
+reflect2.TypeByName("awesome-package.MyStruct")
+// however, if the type has not been used
+// it will be eliminated by compiler, so we can not get it in runtime
+```
+
+# reflect2 get/set interface{}
+
+```go
+valType := reflect2.TypeOf(1)
+i := 1
+j := 10
+valType.Set(&i, &j)
+// i will be 10
+```
+
+to get set `type`, always use its pointer `*type`
+
+# reflect2 get/set unsafe.Pointer
+
+```go
+valType := reflect2.TypeOf(1)
+i := 1
+j := 10
+valType.UnsafeSet(unsafe.Pointer(&i), unsafe.Pointer(&j))
+// i will be 10
+```
+
+to get set `type`, always use its pointer `*type`
+
+# benchmark
+
+Benchmark is not necessary for this package. It does nothing actually.
+As it is just a thin wrapper to make go runtime public. 
+Both `reflect2` and `reflect` call same function 
+provided by `runtime` package exposed by go language.
+
+# unsafe safety
+
+Instead of casting `[]byte` to `sliceHeader` in your application using unsafe.
+We can use reflect2 instead. This way, if `sliceHeader` changes in the future,
+only reflect2 need to be upgraded.
+
+reflect2 tries its best to keep the implementation same as reflect (by testing).
\ No newline at end of file
diff --git a/debian/changelog b/debian/changelog
index 37f5847..94de2cc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-github-modern-go-reflect2 (1.0.1-1) UNRELEASED; urgency=medium
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Tue, 30 Apr 2019 07:36:25 +0000
+
 golang-github-modern-go-reflect2 (1.0.0-1) unstable; urgency=medium
 
   * Initial release (Closes: #901250)
diff --git a/go_below_17.go b/go_below_17.go
index 8114231..65a93c8 100644
--- a/go_below_17.go
+++ b/go_below_17.go
@@ -6,4 +6,4 @@ import "unsafe"
 
 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
 	return nil
-}
\ No newline at end of file
+}
diff --git a/reflect2.go b/reflect2.go
index feabb61..63b49c7 100644
--- a/reflect2.go
+++ b/reflect2.go
@@ -1,9 +1,9 @@
 package reflect2
 
 import (
+	"github.com/modern-go/concurrent"
 	"reflect"
 	"unsafe"
-	"github.com/modern-go/concurrent"
 )
 
 type Type interface {
@@ -136,7 +136,7 @@ type frozenConfig struct {
 func (cfg Config) Froze() *frozenConfig {
 	return &frozenConfig{
 		useSafeImplementation: cfg.UseSafeImplementation,
-		cache:                 concurrent.NewMap(),
+		cache: concurrent.NewMap(),
 	}
 }
 
@@ -150,6 +150,9 @@ func (cfg *frozenConfig) TypeOf(obj interface{}) Type {
 }
 
 func (cfg *frozenConfig) Type2(type1 reflect.Type) Type {
+	if type1 == nil {
+		return nil
+	}
 	cacheKey := uintptr(unpackEFace(type1).data)
 	typeObj, found := cfg.cache.Load(cacheKey)
 	if found {
@@ -213,6 +216,9 @@ func TypeOfPtr(obj interface{}) PtrType {
 }
 
 func Type2(type1 reflect.Type) Type {
+	if type1 == nil {
+		return nil
+	}
 	return ConfigUnsafe.Type2(type1)
 }
 
@@ -279,4 +285,14 @@ func likePtrType(typ reflect.Type) bool {
 func NoEscape(p unsafe.Pointer) unsafe.Pointer {
 	x := uintptr(p)
 	return unsafe.Pointer(x ^ 0)
-}
\ No newline at end of file
+}
+
+func UnsafeCastString(str string) []byte {
+	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
+	sliceHeader := &reflect.SliceHeader{
+		Data: stringHeader.Data,
+		Cap: stringHeader.Len,
+		Len: stringHeader.Len,
+	}
+	return *(*[]byte)(unsafe.Pointer(sliceHeader))
+}
diff --git a/reflect2_kind.go b/reflect2_kind.go
index f13cbe1..62f299e 100644
--- a/reflect2_kind.go
+++ b/reflect2_kind.go
@@ -11,20 +11,20 @@ func DefaultTypeOfKind(kind reflect.Kind) Type {
 }
 
 var kindTypes = map[reflect.Kind]Type{
-	reflect.Bool: TypeOf(true),
-	reflect.Uint8: TypeOf(uint8(0)),
-	reflect.Int8: TypeOf(int8(0)),
-	reflect.Uint16: TypeOf(uint16(0)),
-	reflect.Int16: TypeOf(int16(0)),
-	reflect.Uint32: TypeOf(uint32(0)),
-	reflect.Int32: TypeOf(int32(0)),
-	reflect.Uint64: TypeOf(uint64(0)),
-	reflect.Int64: TypeOf(int64(0)),
-	reflect.Uint: TypeOf(uint(0)),
-	reflect.Int: TypeOf(int(0)),
-	reflect.Float32: TypeOf(float32(0)),
-	reflect.Float64: TypeOf(float64(0)),
-	reflect.Uintptr: TypeOf(uintptr(0)),
-	reflect.String: TypeOf(""),
+	reflect.Bool:          TypeOf(true),
+	reflect.Uint8:         TypeOf(uint8(0)),
+	reflect.Int8:          TypeOf(int8(0)),
+	reflect.Uint16:        TypeOf(uint16(0)),
+	reflect.Int16:         TypeOf(int16(0)),
+	reflect.Uint32:        TypeOf(uint32(0)),
+	reflect.Int32:         TypeOf(int32(0)),
+	reflect.Uint64:        TypeOf(uint64(0)),
+	reflect.Int64:         TypeOf(int64(0)),
+	reflect.Uint:          TypeOf(uint(0)),
+	reflect.Int:           TypeOf(int(0)),
+	reflect.Float32:       TypeOf(float32(0)),
+	reflect.Float64:       TypeOf(float64(0)),
+	reflect.Uintptr:       TypeOf(uintptr(0)),
+	reflect.String:        TypeOf(""),
 	reflect.UnsafePointer: TypeOf(unsafe.Pointer(nil)),
-}
\ No newline at end of file
+}
diff --git a/safe_field.go b/safe_field.go
index f68de45..d4ba1f4 100644
--- a/safe_field.go
+++ b/safe_field.go
@@ -55,4 +55,4 @@ func (field *safeField) Get(obj interface{}) interface{} {
 
 func (field *safeField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer {
 	panic("does not support unsafe operation")
-}
\ No newline at end of file
+}
diff --git a/safe_map.go b/safe_map.go
index 6a1ba23..8836220 100644
--- a/safe_map.go
+++ b/safe_map.go
@@ -76,8 +76,8 @@ func (type2 *safeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
 }
 
 type safeMapIterator struct {
-	i int
-	m reflect.Value
+	i    int
+	m    reflect.Value
 	keys []reflect.Value
 }
 
@@ -98,4 +98,4 @@ func (iter *safeMapIterator) Next() (interface{}, interface{}) {
 
 func (iter *safeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) {
 	panic("does not support unsafe operation")
-}
\ No newline at end of file
+}
diff --git a/safe_slice.go b/safe_slice.go
index 7e348c1..bcce6fd 100644
--- a/safe_slice.go
+++ b/safe_slice.go
@@ -89,4 +89,4 @@ func (type2 *safeSliceType) Cap(obj interface{}) int {
 
 func (type2 *safeSliceType) UnsafeCap(ptr unsafe.Pointer) int {
 	panic("does not support unsafe operation")
-}
\ No newline at end of file
+}
diff --git a/safe_struct.go b/safe_struct.go
index d8eb453..e5fb9b3 100644
--- a/safe_struct.go
+++ b/safe_struct.go
@@ -10,4 +10,20 @@ func (type2 *safeStructType) FieldByName(name string) StructField {
 		panic("field " + name + " not found")
 	}
 	return &safeField{StructField: field}
-}
\ No newline at end of file
+}
+
+func (type2 *safeStructType) Field(i int) StructField {
+	return &safeField{StructField: type2.Type.Field(i)}
+}
+
+func (type2 *safeStructType) FieldByIndex(index []int) StructField {
+	return &safeField{StructField: type2.Type.FieldByIndex(index)}
+}
+
+func (type2 *safeStructType) FieldByNameFunc(match func(string) bool) StructField {
+	field, found := type2.Type.FieldByNameFunc(match)
+	if !found {
+		panic("field match condition not found in " + type2.Type.String())
+	}
+	return &safeField{StructField: field}
+}
diff --git a/safe_type.go b/safe_type.go
index 3cd6331..ee4e7bb 100644
--- a/safe_type.go
+++ b/safe_type.go
@@ -75,4 +75,4 @@ func (type2 *safeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) {
 
 func (type2 *safeType) AssignableTo(anotherType Type) bool {
 	return type2.Type1().AssignableTo(anotherType.Type1())
-}
\ No newline at end of file
+}
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..3d2b976
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+set -e
+echo "" > coverage.txt
+
+for d in $(go list github.com/modern-go/reflect2-tests/... | grep -v vendor); do
+    go test -coverprofile=profile.out -coverpkg=github.com/modern-go/reflect2 $d
+    if [ -f profile.out ]; then
+        cat profile.out >> coverage.txt
+        rm profile.out
+    fi
+done
diff --git a/test15/map_test.go b/test15/map_test.go
deleted file mode 100644
index 11b3964..0000000
--- a/test15/map_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package test
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_map(t *testing.T) {
-	var pInt = func(val int) *int {
-		return &val
-	}
-	valType := reflect2.TypeOf(map[int]int{}).(reflect2.MapType)
-	m := map[int]int{}
-	valType.SetIndex(&m, pInt(1), pInt(1))
-	if m[1] != 1 {
-		t.Fail()
-	}
-}
\ No newline at end of file
diff --git a/tests/array_test.go b/tests/array_test.go
deleted file mode 100644
index 8c91098..0000000
--- a/tests/array_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_array(t *testing.T) {
-	var pInt = func(val int) *int {
-		return &val
-	}
-	t.Run("New", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([2]int{})
-		obj := valType.New()
-		(*(obj.(*[2]int)))[0] = 100
-		(*(obj.(*[2]int)))[1] = 200
-		return obj
-	}))
-	t.Run("Indirect", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([2]int{})
-		return valType.Indirect(&[2]int{})
-	}))
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := [2]int{}
-		valType := api.TypeOf(obj).(reflect2.ArrayType)
-		valType.SetIndex(&obj, 0, pInt(100))
-		valType.SetIndex(&obj, 1, pInt(200))
-		return obj
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := [2]int{1, 2}
-		valType := api.TypeOf(obj).(reflect2.ArrayType)
-		return []interface{} {
-			valType.GetIndex(&obj, 0),
-			valType.GetIndex(&obj, 1),
-		}
-	}))
-}
diff --git a/tests/int_test.go b/tests/int_test.go
deleted file mode 100644
index 7fd60e4..0000000
--- a/tests/int_test.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test"
-	"unsafe"
-	"github.com/modern-go/test/must"
-	"context"
-)
-
-func Test_int(t *testing.T) {
-	t.Run("New", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf(1)
-		obj := valType.New()
-		*obj.(*int) = 100
-		return obj
-	}))
-	t.Run("PackEFace", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(1)
-		hundred := 100
-		must.Equal(&hundred, valType.PackEFace(unsafe.Pointer(&hundred)))
-	}))
-	t.Run("Indirect", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(1)
-		hundred := 100
-		must.Equal(100, valType.Indirect(&hundred))
-	}))
-	t.Run("Indirect", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(1)
-		hundred := 100
-		must.Equal(100, valType.UnsafeIndirect(unsafe.Pointer(&hundred)))
-	}))
-	t.Run("Set", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf(1)
-		i := 1
-		j := 10
-		valType.Set(&i, &j)
-		return i
-	}))
-}
diff --git a/tests/map_elem_array_test.go b/tests/map_elem_array_test.go
deleted file mode 100644
index 607f624..0000000
--- a/tests/map_elem_array_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_map_elem_array(t *testing.T) {
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[int][2]*int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, [2]*int{(*int)(reflect2.PtrOf(1)), (*int)(reflect2.PtrOf(2))})
-		valType.SetIndex(obj, 3, [2]*int{(*int)(reflect2.PtrOf(3)), (*int)(reflect2.PtrOf(4))})
-		return obj
-	}))
-	t.Run("SetIndex zero length array", testOp(func(api reflect2.API) interface{} {
-		obj := map[int][0]*int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, [0]*int{})
-		valType.SetIndex(obj, 3, [0]*int{})
-		return obj
-	}))
-	t.Run("SetIndex single ptr array", testOp(func(api reflect2.API) interface{} {
-		obj := map[int][1]*int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, [1]*int{(*int)(reflect2.PtrOf(1))})
-		valType.SetIndex(obj, 3, [1]*int{})
-		return obj
-	}))
-	t.Run("SetIndex single chan array", testOp(func(api reflect2.API) interface{} {
-		obj := map[int][1]chan int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, [1]chan int{})
-		valType.SetIndex(obj, 3, [1]chan int{})
-		return obj
-	}))
-	t.Run("SetIndex single func array", testOp(func(api reflect2.API) interface{} {
-		obj := map[int][1]func(){}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, [1]func(){})
-		valType.SetIndex(obj, 3, [1]func(){})
-		return obj
-	}))
-}
diff --git a/tests/map_elem_bytes_test.go b/tests/map_elem_bytes_test.go
deleted file mode 100644
index d6d894e..0000000
--- a/tests/map_elem_bytes_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test"
-	"github.com/modern-go/test/must"
-	"context"
-)
-
-func Test_map_elem_bytes(t *testing.T) {
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[int][]byte{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, []byte("hello"))
-		valType.SetIndex(obj, 3, nil)
-		return obj
-	}))
-	t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
-		obj := map[int][]byte{}
-		valType := reflect2.TypeOf(obj).(reflect2.MapType)
-		hello := []byte("hello")
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), reflect2.PtrOf(2), reflect2.PtrOf(hello))
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), reflect2.PtrOf(3), nil)
-		must.Equal([]byte("hello"), obj[2])
-		must.Nil(obj[3])
-	}))
-	t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) {
-		obj := map[int][]byte{2: []byte("hello")}
-		valType := reflect2.TypeOf(obj).(reflect2.MapType)
-		elem := valType.UnsafeGetIndex(reflect2.PtrOf(obj), reflect2.PtrOf(2))
-		must.Equal([]byte("hello"), valType.Elem().PackEFace(elem))
-	}))
-}
diff --git a/tests/map_elem_eface_test.go b/tests/map_elem_eface_test.go
deleted file mode 100644
index d6cd51e..0000000
--- a/tests/map_elem_eface_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test/must"
-
-	"github.com/modern-go/test"
-	"context"
-)
-
-func Test_map_elem_eface(t *testing.T) {
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[int]interface{}{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, 4)
-		valType.SetIndex(obj, 3, nil)
-		return obj
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[int]interface{}{3: 9, 2: nil}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		return []interface{}{
-			valType.GetIndex(obj, 3),
-			valType.GetIndex(obj, 2),
-			valType.GetIndex(obj, 0),
-		}
-	}))
-	t.Run("TryGetIndex", test.Case(func(ctx context.Context) {
-		obj := map[int]interface{}{3: 9, 2: nil}
-		valType := reflect2.TypeOf(obj).(reflect2.MapType)
-		elem, found := valType.TryGetIndex(obj, 3)
-		must.Equal(9, elem)
-		must.Pass(found)
-		elem, found = valType.TryGetIndex(obj, 2)
-		must.Nil(elem)
-		must.Pass(found)
-		elem, found = valType.TryGetIndex(obj, 0)
-		must.Nil(elem)
-		must.Pass(!found)
-	}))
-	t.Run("Iterate", testOp(func(api reflect2.API) interface{} {
-		obj := map[int]interface{}{2: 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		iter := valType.Iterate(obj)
-		must.Pass(iter.HasNext(), "api", api)
-		key1, elem1 := iter.Next()
-		must.Pass(!iter.HasNext(), "api", api)
-		return []interface{}{key1, elem1}
-	}))
-}
\ No newline at end of file
diff --git a/tests/map_elem_map_test.go b/tests/map_elem_map_test.go
deleted file mode 100644
index 3cc4dfe..0000000
--- a/tests/map_elem_map_test.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_map_elem_map(t *testing.T) {
-	var pInt = func(val int) *int {
-		return &val
-	}
-	var pMap = func(val map[int]int) *map[int]int {
-		return &val
-	}
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[int]map[int]int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(&obj, pInt(2), pMap(map[int]int{4:4}))
-		valType.SetIndex(&obj, pInt(3), pMap(map[int]int{9:9}))
-		valType.SetIndex(&obj, pInt(3), pMap(nil))
-		return obj
-	}))
-}
\ No newline at end of file
diff --git a/tests/map_elem_struct_test.go b/tests/map_elem_struct_test.go
deleted file mode 100644
index ec2dd2d..0000000
--- a/tests/map_elem_struct_test.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"time"
-)
-
-func Test_map_elem_struct(t *testing.T) {
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[int]time.Time{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, time.Time{})
-		valType.SetIndex(obj, 3, time.Time{})
-		return obj
-	}))
-	t.Run("SetIndex single ptr struct", testOp(func(api reflect2.API) interface{} {
-		type TestObject struct {
-			Field1 *int
-		}
-		obj := map[int]TestObject{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, TestObject{})
-		valType.SetIndex(obj, 3, TestObject{})
-		return obj
-	}))
-	t.Run("SetIndex single map struct", testOp(func(api reflect2.API) interface{} {
-		type TestObject struct {
-			Field1 map[int]int
-		}
-		obj := map[int]TestObject{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, TestObject{})
-		valType.SetIndex(obj, 3, TestObject{})
-		return obj
-	}))
-	t.Run("SetIndex single chan struct", testOp(func(api reflect2.API) interface{} {
-		type TestObject struct {
-			Field1 chan int
-		}
-		obj := map[int]TestObject{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, TestObject{})
-		valType.SetIndex(obj, 3, TestObject{})
-		return obj
-	}))
-	t.Run("SetIndex single func struct", testOp(func(api reflect2.API) interface{} {
-		type TestObject struct {
-			Field1 func()
-		}
-		obj := map[int]TestObject{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, 2, TestObject{})
-		valType.SetIndex(obj, 3, TestObject{})
-		return obj
-	}))
-}
diff --git a/tests/map_key_eface_test.go b/tests/map_key_eface_test.go
deleted file mode 100644
index df57e8f..0000000
--- a/tests/map_key_eface_test.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test/must"
-)
-
-func Test_map_key_eface(t *testing.T) {
-	var pEFace = func(val interface{}) interface{} {
-		return &val
-	}
-	var pInt = func(val int) *int {
-		return &val
-	}
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[interface{}]int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(&obj, pEFace(2), pInt(4))
-		valType.SetIndex(&obj, pEFace(3), pInt(9))
-		valType.SetIndex(&obj, pEFace(nil), pInt(9))
-		return obj
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[interface{}]int{3: 9, 2: 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		return []interface{}{
-			valType.GetIndex(&obj, pEFace(3)),
-			valType.GetIndex(&obj, pEFace(0)),
-			valType.GetIndex(&obj, pEFace(nil)),
-			valType.GetIndex(&obj, pEFace("")),
-		}
-	}))
-	t.Run("Iterate", testOp(func(api reflect2.API) interface{} {
-		obj := map[interface{}]int{2: 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		iter := valType.Iterate(obj)
-		must.Pass(iter.HasNext(), "api", api)
-		key1, elem1 := iter.Next()
-		must.Pass(!iter.HasNext(), "api", api)
-		return []interface{}{key1, elem1}
-	}))
-}
diff --git a/tests/map_key_iface_test.go b/tests/map_key_iface_test.go
deleted file mode 100644
index b8774af..0000000
--- a/tests/map_key_iface_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test/must"
-)
-
-type intError int
-
-func (err intError) Error() string {
-	return ""
-}
-
-func Test_map_iface_key(t *testing.T) {
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[error]int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(obj, intError(2), 4)
-		valType.SetIndex(obj, intError(2), 9)
-		valType.SetIndex(obj, nil, 9)
-		must.Panic(func() {
-			valType.SetIndex(obj, "", 9)
-		})
-		return obj
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[error]int{intError(3): 9, intError(2): 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		must.Panic(func() {
-			valType.GetIndex(obj, "")
-		})
-		return []interface{}{
-			valType.GetIndex(obj, intError(3)),
-			valType.GetIndex(obj, nil),
-		}
-	}))
-	t.Run("Iterate", testOp(func(api reflect2.API) interface{} {
-		obj := map[error]int{intError(2): 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		iter := valType.Iterate(obj)
-		must.Pass(iter.HasNext(), "api", api)
-		key1, elem1 := iter.Next()
-		must.Pass(!iter.HasNext(), "api", api)
-		return []interface{}{key1, elem1}
-	}))
-}
diff --git a/tests/map_key_ptr_test.go b/tests/map_key_ptr_test.go
deleted file mode 100644
index 7c905f7..0000000
--- a/tests/map_key_ptr_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test/must"
-	"github.com/modern-go/test"
-
-	"unsafe"
-	"context"
-)
-
-func Test_map_key_ptr(t *testing.T) {
-	var pInt = func(val int) *int {
-		return &val
-	}
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[*int]int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		key := pInt(2)
-		valType.SetIndex(obj, &key, 4)
-		valType.SetIndex(obj, &key, 9)
-		//valType.SetIndex(obj, nil, 9)
-		return obj[pInt(2)]
-	}))
-	t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
-		obj := map[*int]int{}
-		valType := reflect2.TypeOf(obj).(reflect2.MapType)
-		v := pInt(2)
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), unsafe.Pointer(v), reflect2.PtrOf(4))
-		must.Equal(4, obj[v])
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[*int]int{pInt(3): 9, pInt(2): 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		return []interface{}{
-			valType.GetIndex(obj, pInt(3)),
-			valType.GetIndex(obj, pInt(2)),
-			valType.GetIndex(obj, nil),
-		}
-	}))
-	t.Run("Iterate", testOp(func(api reflect2.API) interface{} {
-		obj := map[*int]int{pInt(2): 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		iter := valType.Iterate(&obj)
-		must.Pass(iter.HasNext(), "api", api)
-		key1, elem1 := iter.Next()
-		must.Pass(!iter.HasNext(), "api", api)
-		return []interface{}{key1, elem1}
-	}))
-}
diff --git a/tests/map_test.go b/tests/map_test.go
deleted file mode 100644
index 131baa4..0000000
--- a/tests/map_test.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test/must"
-
-	"github.com/modern-go/test"
-	"unsafe"
-	"reflect"
-	"context"
-)
-
-func Test_map(t *testing.T) {
-	var pInt = func(val int) *int {
-		return &val
-	}
-	t.Run("New", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf(map[int]int{})
-		m := valType.New().(*map[int]int)
-		return m
-	}))
-	t.Run("IsNil", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf(map[int]int{})
-		var nilMap map[int]int
-		m := map[int]int{}
-		return []interface{}{
-			valType.IsNil(&nilMap),
-			valType.IsNil(&m),
-		}
-	}))
-	t.Run("MakeMap", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf(map[int]int{}).(reflect2.MapType)
-		m := *(valType.MakeMap(0).(*map[int]int))
-		m[2] = 4
-		m[3] = 9
-		return m
-	}))
-	t.Run("UnsafeMakeMap", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(map[int]int{}).(reflect2.MapType)
-		m := *(*map[int]int)(valType.UnsafeMakeMap(0))
-		m[2] = 4
-		m[3] = 9
-	}))
-	t.Run("PackEFace", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(map[int]int{}).(reflect2.MapType)
-		m := valType.UnsafeMakeMap(0)
-		must.Equal(&map[int]int{}, valType.PackEFace(unsafe.Pointer(m)))
-	}))
-	t.Run("Indirect", testOp(func(api reflect2.API) interface{} {
-		valType := reflect2.TypeOf(map[int]int{})
-		return valType.Indirect(&map[int]int{})
-	}))
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[int]int{}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		valType.SetIndex(&obj, pInt(2), pInt(4))
-		valType.SetIndex(&obj, pInt(3), pInt(9))
-		must.Equal(4, obj[2])
-		return obj
-	}))
-	t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
-		obj := map[int]int{}
-		valType := reflect2.TypeOf(obj).(reflect2.MapType)
-		valType.UnsafeSetIndex(unsafe.Pointer(&obj), reflect2.PtrOf(2), reflect2.PtrOf(4))
-		must.Equal(map[int]int{2: 4}, obj)
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := map[int]int{3: 9, 2: 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		return []interface{}{
-			*valType.GetIndex(&obj, pInt(3)).(*int),
-			valType.GetIndex(&obj, pInt(0)).(*int),
-		}
-	}))
-	t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) {
-		obj := map[int]int{3: 9, 2: 4}
-		valType := reflect2.TypeOf(obj).(reflect2.MapType)
-		elem := valType.UnsafeGetIndex(unsafe.Pointer(&obj), reflect2.PtrOf(3))
-		must.Equal(9, *(*int)(elem))
-	}))
-	t.Run("Iterate", testOp(func(api reflect2.API) interface{} {
-		obj := map[int]int{2: 4}
-		valType := api.TypeOf(obj).(reflect2.MapType)
-		iter := valType.Iterate(&obj)
-		must.Pass(iter.HasNext(), "api", api)
-		key1, elem1 := iter.Next()
-		must.Pass(!iter.HasNext(), "api", api)
-		return []interface{}{key1, elem1}
-	}))
-	t.Run("UnsafeIterate", test.Case(func(ctx context.Context) {
-		obj := map[int]int{2: 4}
-		valType := reflect2.TypeOf(obj).(reflect2.MapType)
-		iter := valType.UnsafeIterate(unsafe.Pointer(&obj))
-		must.Pass(iter.HasNext())
-		key, elem := iter.UnsafeNext()
-		must.Equal(2, *(*int)(key))
-		must.Equal(4, *(*int)(elem))
-	}))
-}
-
-func Benchmark_map_unsafe(b *testing.B) {
-	obj := map[int]int{}
-	valType := reflect2.TypeOf(obj).(*reflect2.UnsafeMapType)
-	m := unsafe.Pointer(&obj)
-	b.ReportAllocs()
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		valType.UnsafeSetIndex(m, reflect2.PtrOf(2), reflect2.PtrOf(4))
-	}
-}
-
-func Benchmark_map_safe(b *testing.B) {
-	obj := map[int]int{}
-	val := reflect.ValueOf(obj)
-	b.ReportAllocs()
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		val.SetMapIndex(reflect.ValueOf(2), reflect.ValueOf(4))
-	}
-}
diff --git a/tests/op_test.go b/tests/op_test.go
deleted file mode 100644
index fa3bd45..0000000
--- a/tests/op_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package tests
-
-import (
-	"github.com/modern-go/reflect2"
-	"testing"
-
-	"github.com/modern-go/test/must"
-	"github.com/modern-go/test"
-	"context"
-)
-
-func testOp(f func(api reflect2.API) interface{}) func(t *testing.T) {
-	return test.Case(func(ctx context.Context) {
-		unsafeResult := f(reflect2.ConfigUnsafe)
-		safeResult := f(reflect2.ConfigSafe)
-		must.Equal(safeResult, unsafeResult)
-	})
-}
diff --git a/tests/slice_array_test.go b/tests/slice_array_test.go
deleted file mode 100644
index 89dbbe7..0000000
--- a/tests/slice_array_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_slice_array(t *testing.T) {
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := [][1]int{{}, {}}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, [1]int{1})
-		valType.SetIndex(obj, 1, [1]int{2})
-		return obj
-	}))
-	t.Run("SetIndex single ptr struct", testOp(func(api reflect2.API) interface{} {
-		obj := [][1]*int{{}, {}}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, [1]*int{})
-		valType.SetIndex(obj, 1, [1]*int{})
-		return obj
-	}))
-	t.Run("SetIndex single chan struct", testOp(func(api reflect2.API) interface{} {
-		obj := [][1]chan int{{}, {}}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, [1]chan int{})
-		valType.SetIndex(obj, 1, [1]chan int{})
-		return obj
-	}))
-	t.Run("SetIndex single func struct", testOp(func(api reflect2.API) interface{} {
-		obj := [][1]func(){{}, {}}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, [1]func(){})
-		valType.SetIndex(obj, 1, [1]func(){})
-		return obj
-	}))
-}
diff --git a/tests/slice_bytes_test.go b/tests/slice_bytes_test.go
deleted file mode 100644
index ef1aa68..0000000
--- a/tests/slice_bytes_test.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_slice_bytes(t *testing.T) {
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := [][]byte{[]byte("hello"), []byte("world")}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(&obj, 0, []byte("hi"))
-		valType.SetIndex(&obj, 1, []byte("there"))
-		return obj
-	}))
-}
\ No newline at end of file
diff --git a/tests/slice_eface_test.go b/tests/slice_eface_test.go
deleted file mode 100644
index 950ad33..0000000
--- a/tests/slice_eface_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test"
-
-	"github.com/modern-go/test/must"
-	"unsafe"
-	"github.com/modern-go/test/should"
-	"fmt"
-	"context"
-)
-
-func Test_slice_eface(t *testing.T) {
-	t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]interface{}{}).(reflect2.SliceType)
-		obj := valType.MakeSlice(5, 10)
-		obj.([]interface{})[0] = 100
-		obj.([]interface{})[4] = 20
-		return obj
-	}))
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []interface{}{1, nil}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		elem0 := interface{}(100)
-		valType.SetIndex(obj, 0, &elem0)
-		elem1 := interface{}(20)
-		valType.SetIndex(obj, 1, &elem1)
-		return obj
-	}))
-	t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
-		obj := []interface{}{1, 2}
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		var elem0 interface{} = 100
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, unsafe.Pointer(&elem0))
-		var elem1 interface{} = 10
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, unsafe.Pointer(&elem1))
-		must.Equal([]interface{}{100, 10}, obj)
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []interface{}{1, nil}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		fmt.Println(api, *valType.GetIndex(obj, 0).(*interface{}))
-		return []interface{}{
-			valType.GetIndex(obj, 0),
-			valType.GetIndex(obj, 1),
-		}
-	}))
-	t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) {
-		obj := []interface{}{1, nil}
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		elem0 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 0)
-		must.Equal(1, *(*interface{})(elem0))
-	}))
-	t.Run("Append", testOp(func(api reflect2.API) interface{} {
-		obj := make([]interface{}, 2, 3)
-		obj[0] = 1
-		obj[1] = 2
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.Append(&obj, 3)
-		// will trigger grow
-		valType.Append(&obj, 4)
-		return obj
-	}))
-	t.Run("UnsafeAppend", test.Case(func(ctx context.Context) {
-		obj := make([]interface{}, 2, 3)
-		obj[0] = 1
-		obj[1] = 2
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		ptr := reflect2.PtrOf(obj)
-		var elem2 interface{} = 3
-		valType.UnsafeAppend(ptr, unsafe.Pointer(&elem2))
-		var elem3 interface{} = 4
-		valType.UnsafeAppend(ptr, unsafe.Pointer(&elem3))
-		should.Equal([]interface{}{1, 2, 3, 4}, valType.PackEFace(ptr))
-	}))
-}
diff --git a/tests/slice_iface_test.go b/tests/slice_iface_test.go
deleted file mode 100644
index 0a94d79..0000000
--- a/tests/slice_iface_test.go
+++ /dev/null
@@ -1,81 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"errors"
-	"github.com/modern-go/test"
-
-	"unsafe"
-	"github.com/modern-go/test/must"
-	"context"
-)
-
-func Test_slice_iface(t *testing.T) {
-	var pError = func(msg string) *error {
-		err := errors.New(msg)
-		return &err
-	}
-	t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]error{}).(reflect2.SliceType)
-		obj := *(valType.MakeSlice(5, 10).(*[]error))
-		obj[0] = errors.New("hello")
-		obj[4] = errors.New("world")
-		return obj
-	}))
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []error{errors.New("hello"), nil}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(&obj, 0, pError("hi"))
-		valType.SetIndex(&obj, 1, pError("world"))
-		return obj
-	}))
-	t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
-		obj := []error{errors.New("hello"), nil}
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		elem0 := errors.New("hi")
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, unsafe.Pointer(&elem0))
-		elem1 := errors.New("world")
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, unsafe.Pointer(&elem1))
-		must.Equal([]error{elem0, elem1}, obj)
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []error{errors.New("hello"), nil}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		return []interface{}{
-			valType.GetIndex(&obj, 0),
-			valType.GetIndex(&obj, 1),
-		}
-	}))
-	t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) {
-		obj := []error{errors.New("hello"), nil}
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		elem0 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 0)
-		must.Equal(errors.New("hello"), *(*error)(elem0))
-	}))
-	t.Run("Append", testOp(func(api reflect2.API) interface{} {
-		obj := make([]error, 2, 3)
-		obj[0] = errors.New("1")
-		obj[1] = errors.New("2")
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		ptr := &obj
-		valType.Append(ptr, pError("3"))
-		// will trigger grow
-		valType.Append(ptr, pError("4"))
-		return ptr
-	}))
-	t.Run("UnsafeAppend", test.Case(func(ctx context.Context) {
-		obj := make([]error, 2, 3)
-		obj[0] = errors.New("1")
-		obj[1] = errors.New("2")
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		ptr := reflect2.PtrOf(obj)
-		elem2 := errors.New("3")
-		valType.UnsafeAppend(ptr, unsafe.Pointer(&elem2))
-		elem3 := errors.New("4")
-		valType.UnsafeAppend(ptr, unsafe.Pointer(&elem3))
-		must.Equal(&[]error{
-			obj[0], obj[1], elem2, elem3,
-		}, valType.PackEFace(ptr))
-	}))
-}
diff --git a/tests/slice_map_test.go b/tests/slice_map_test.go
deleted file mode 100644
index f01a212..0000000
--- a/tests/slice_map_test.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_slice_map(t *testing.T) {
-	t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]map[int]int{}).(reflect2.SliceType)
-		obj := valType.MakeSlice(5, 10)
-		obj.([]map[int]int)[0] = map[int]int{1:1}
-		obj.([]map[int]int)[4] = map[int]int{2:2}
-		return obj
-	}))
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []map[int]int{{1: 1}, nil}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, &map[int]int{10:10})
-		valType.SetIndex(obj, 1, &map[int]int{2:2})
-		return obj
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []map[int]int{{1:1}, nil}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		return []interface{}{
-			valType.GetIndex(&obj, 0),
-			valType.GetIndex(&obj, 1),
-			valType.GetIndex(obj, 0),
-			valType.GetIndex(obj, 1),
-		}
-	}))
-	t.Run("Append", testOp(func(api reflect2.API) interface{} {
-		obj := make([]map[int]int, 2, 3)
-		obj[0] = map[int]int{1:1}
-		obj[1] = map[int]int{2:2}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.Append(obj, map[int]int{3:3})
-		// will trigger grow
-		valType.Append(obj, map[int]int{4:4})
-		return obj
-	}))
-}
\ No newline at end of file
diff --git a/tests/slice_ptr_test.go b/tests/slice_ptr_test.go
deleted file mode 100644
index a381be4..0000000
--- a/tests/slice_ptr_test.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test"
-
-	"unsafe"
-	"github.com/modern-go/test/must"
-	"context"
-)
-
-func Test_slice_ptr(t *testing.T) {
-	var pInt = func(val int) *int {
-		return &val
-	}
-	t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]*int{}).(reflect2.SliceType)
-		obj := valType.MakeSlice(5, 10)
-		obj.([]*int)[0] = pInt(1)
-		obj.([]*int)[4] = pInt(5)
-		return obj
-	}))
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []*int{pInt(1), nil}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, pInt(2))
-		valType.SetIndex(obj, 1, pInt(3))
-		return obj
-	}))
-	t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
-		obj := []*int{pInt(1), nil}
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, unsafe.Pointer(pInt(2)))
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, unsafe.Pointer(pInt(1)))
-		must.Equal([]*int{pInt(2), pInt(1)}, obj)
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []*int{pInt(1), nil}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		return []interface{}{
-			valType.GetIndex(&obj, 0),
-			valType.GetIndex(&obj, 1),
-			valType.GetIndex(obj, 0),
-			valType.GetIndex(obj, 1),
-		}
-	}))
-	t.Run("Append", testOp(func(api reflect2.API) interface{} {
-		obj := make([]*int, 2, 3)
-		obj[0] = pInt(1)
-		obj[1] = pInt(2)
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.Append(obj, pInt(3))
-		// will trigger grow
-		valType.Append(obj, pInt(4))
-		return obj
-	}))
-}
diff --git a/tests/slice_string_test.go b/tests/slice_string_test.go
deleted file mode 100644
index 24cc781..0000000
--- a/tests/slice_string_test.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_slice_string(t *testing.T) {
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []string{"hello", "world"}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(&obj, 0, "hi")
-		valType.SetIndex(&obj, 1, "there")
-		return obj
-	}))
-}
\ No newline at end of file
diff --git a/tests/slice_struct_test.go b/tests/slice_struct_test.go
deleted file mode 100644
index 594c286..0000000
--- a/tests/slice_struct_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_slice_struct(t *testing.T) {
-	var pInt = func(val int) *int {
-		return &val
-	}
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		type TestObject struct {
-			Field1 float64
-			Field2 float64
-		}
-		obj := []TestObject{{}, {}}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, &TestObject{1, 3})
-		valType.SetIndex(obj, 1, &TestObject{2, 4})
-		return obj
-	}))
-	t.Run("SetIndex single ptr struct", testOp(func(api reflect2.API) interface{} {
-		type TestObject struct {
-			Field1 *int
-		}
-		obj := []TestObject{{}, {}}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, &TestObject{pInt(1)})
-		valType.SetIndex(obj, 1, &TestObject{pInt(2)})
-		return obj
-	}))
-	t.Run("SetIndex single chan struct", testOp(func(api reflect2.API) interface{} {
-		type TestObject struct {
-			Field1 chan int
-		}
-		obj := []TestObject{{}, {}}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, TestObject{})
-		valType.SetIndex(obj, 1, TestObject{})
-		return obj
-	}))
-	t.Run("SetIndex single func struct", testOp(func(api reflect2.API) interface{} {
-		type TestObject struct {
-			Field1 func()
-		}
-		obj := []TestObject{{}, {}}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(obj, 0, TestObject{})
-		valType.SetIndex(obj, 1, TestObject{})
-		return obj
-	}))
-}
\ No newline at end of file
diff --git a/tests/slice_test.go b/tests/slice_test.go
deleted file mode 100644
index 2b5f98d..0000000
--- a/tests/slice_test.go
+++ /dev/null
@@ -1,115 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test"
-
-	"github.com/modern-go/test/must"
-	"context"
-)
-
-func Test_slice(t *testing.T) {
-	var pInt = func(val int) *int {
-		return &val
-	}
-	t.Run("New", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]int{})
-		obj := *valType.New().(*[]int)
-		obj = append(obj, 1)
-		return obj
-	}))
-	t.Run("IsNil", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]int{})
-		var nilSlice []int
-		s := []int{}
-		return []interface{}{
-			valType.IsNil(&nilSlice),
-			valType.IsNil(&s),
-			valType.IsNil(nil),
-		}
-	}))
-	t.Run("SetNil", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]int{}).(reflect2.SliceType)
-		s := []int{1}
-		valType.SetNil(&s)
-		return s
-	}))
-	t.Run("Set", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]int{}).(reflect2.SliceType)
-		s1 := []int{1}
-		s2 := []int{2}
-		valType.Set(&s1, &s2)
-		return s1
-	}))
-	t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf([]int{}).(reflect2.SliceType)
-		obj := *(valType.MakeSlice(5, 10).(*[]int))
-		obj[0] = 100
-		obj[4] = 20
-		return obj
-	}))
-	t.Run("UnsafeMakeSlice", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf([]int{}).(reflect2.SliceType)
-		obj := valType.UnsafeMakeSlice(5, 10)
-		must.Equal(&[]int{0, 0, 0, 0, 0}, valType.PackEFace(obj))
-	}))
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []int{1, 2}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		valType.SetIndex(&obj, 0, pInt(100))
-		valType.SetIndex(&obj, 1, pInt(20))
-		return obj
-	}))
-	t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
-		obj := []int{1, 2}
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, reflect2.PtrOf(100))
-		valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, reflect2.PtrOf(10))
-		must.Equal([]int{100, 10}, obj)
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := []int{1, 2}
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		return []interface{}{
-			valType.GetIndex(&obj, 1).(*int),
-		}
-	}))
-	t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) {
-		obj := []int{1, 2}
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		elem0 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 0)
-		must.Equal(1, *(*int)(elem0))
-		elem1 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 1)
-		must.Equal(2, *(*int)(elem1))
-	}))
-	t.Run("Append", testOp(func(api reflect2.API) interface{} {
-		obj := make([]int, 2, 3)
-		obj[0] = 1
-		obj[1] = 2
-		valType := api.TypeOf(obj).(reflect2.SliceType)
-		ptr := &obj
-		valType.Append(ptr, pInt(3))
-		// will trigger grow
-		valType.Append(ptr, pInt(4))
-		return ptr
-	}))
-	t.Run("UnsafeAppend", test.Case(func(ctx context.Context) {
-		obj := make([]int, 2, 3)
-		obj[0] = 1
-		obj[1] = 2
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		ptr := reflect2.PtrOf(obj)
-		valType.UnsafeAppend(ptr, reflect2.PtrOf(3))
-		valType.UnsafeAppend(ptr, reflect2.PtrOf(4))
-		must.Equal(&[]int{1, 2, 3, 4}, valType.PackEFace(ptr))
-	}))
-	t.Run("Grow", testOp(func(api reflect2.API) interface{} {
-		obj := make([]int, 2, 3)
-		obj[0] = 1
-		obj[1] = 2
-		valType := reflect2.TypeOf(obj).(reflect2.SliceType)
-		valType.Grow(&obj, 4)
-		return obj
-	}))
-}
diff --git a/tests/struct_eface_test.go b/tests/struct_eface_test.go
deleted file mode 100644
index ce1e997..0000000
--- a/tests/struct_eface_test.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-)
-
-func Test_struct_eface(t *testing.T) {
-	type TestObject struct {
-		Field1 interface{}
-	}
-	var pEFace = func(val interface{}) interface{} {
-		return &val
-	}
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf(TestObject{}).(reflect2.StructType)
-		field1 := valType.FieldByName("Field1")
-		obj := TestObject{}
-		field1.Set(&obj, pEFace(100))
-		return obj
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := TestObject{Field1: 100}
-		valType := api.TypeOf(obj).(reflect2.StructType)
-		field1 := valType.FieldByName("Field1")
-		return field1.Get(&obj)
-	}))
-}
\ No newline at end of file
diff --git a/tests/struct_ptr_test.go b/tests/struct_ptr_test.go
deleted file mode 100644
index 889d3af..0000000
--- a/tests/struct_ptr_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package tests
-
-import (
-	"testing"
-
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test/must"
-	"github.com/modern-go/test"
-	"context"
-)
-
-func Test_struct_ptr(t *testing.T) {
-	type TestObject struct {
-		Field1 *int
-	}
-	t.Run("PackEFace", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(TestObject{})
-		ptr := valType.UnsafeNew()
-		must.Equal(&TestObject{}, valType.PackEFace(ptr))
-	}))
-	t.Run("Indirect", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(TestObject{})
-		must.Equal(TestObject{}, valType.Indirect(&TestObject{}))
-	}))
-}
\ No newline at end of file
diff --git a/tests/struct_test.go b/tests/struct_test.go
deleted file mode 100644
index 4f69aad..0000000
--- a/tests/struct_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package tests
-
-import (
-	"testing"
-	"github.com/modern-go/reflect2"
-	"github.com/modern-go/test"
-
-	"unsafe"
-	"github.com/modern-go/test/must"
-	"context"
-)
-
-func Test_struct(t *testing.T) {
-	type TestObject struct {
-		Field1 int
-		Field2 int
-	}
-	var pInt = func(val int) *int {
-		return &val
-	}
-	t.Run("New", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf(TestObject{})
-		obj := valType.New()
-		obj.(*TestObject).Field1 = 20
-		obj.(*TestObject).Field2 = 100
-		return obj
-	}))
-	t.Run("PackEFace", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(TestObject{})
-		ptr := valType.UnsafeNew()
-		must.Equal(&TestObject{}, valType.PackEFace(ptr))
-	}))
-	t.Run("Indirect", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(TestObject{})
-		must.Equal(TestObject{}, valType.Indirect(&TestObject{}))
-	}))
-	t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
-		valType := api.TypeOf(TestObject{}).(reflect2.StructType)
-		field1 := valType.FieldByName("Field1")
-		obj := TestObject{}
-		field1.Set(&obj, pInt(100))
-		return obj
-	}))
-	t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
-		valType := reflect2.TypeOf(TestObject{}).(reflect2.StructType)
-		field1 := valType.FieldByName("Field1")
-		obj := TestObject{}
-		field1.UnsafeSet(unsafe.Pointer(&obj), reflect2.PtrOf(100))
-		must.Equal(100, obj.Field1)
-	}))
-	t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
-		obj := TestObject{Field1: 100}
-		valType := api.TypeOf(obj).(reflect2.StructType)
-		field1 := valType.FieldByName("Field1")
-		return field1.Get(&obj)
-	}))
-	t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) {
-		obj := TestObject{Field1: 100}
-		valType := reflect2.TypeOf(obj).(reflect2.StructType)
-		field1 := valType.FieldByName("Field1")
-		value := field1.UnsafeGet(unsafe.Pointer(&obj))
-		must.Equal(100, *(*int)(value))
-	}))
-}
diff --git a/type_map.go b/type_map.go
index 122141f..3acfb55 100644
--- a/type_map.go
+++ b/type_map.go
@@ -1,10 +1,11 @@
 package reflect2
 
 import (
-	"unsafe"
 	"reflect"
 	"runtime"
 	"strings"
+	"sync"
+	"unsafe"
 )
 
 // typelinks1 for 1.5 ~ 1.6
@@ -15,9 +16,17 @@ func typelinks1() [][]unsafe.Pointer
 //go:linkname typelinks2 reflect.typelinks
 func typelinks2() (sections []unsafe.Pointer, offset [][]int32)
 
-var types = map[string]reflect.Type{}
+// initOnce guards initialization of types and packages
+var initOnce sync.Once
+
+var types map[string]reflect.Type
+var packages map[string]map[string]reflect.Type
+
+// discoverTypes initializes types and packages
+func discoverTypes() {
+	types = make(map[string]reflect.Type)
+	packages = make(map[string]map[string]reflect.Type)
 
-func init() {
 	ver := runtime.Version()
 	if ver == "go1.5" || strings.HasPrefix(ver, "go1.5.") {
 		loadGo15Types()
@@ -36,11 +45,25 @@ func loadGo15Types() {
 			(*emptyInterface)(unsafe.Pointer(&obj)).word = typePtr
 			typ := obj.(reflect.Type)
 			if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
-				types[typ.Elem().String()] = typ.Elem()
+				loadedType := typ.Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
 			}
 			if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Ptr &&
 				typ.Elem().Elem().Kind() == reflect.Struct {
-				types[typ.Elem().Elem().String()] = typ.Elem().Elem()
+				loadedType := typ.Elem().Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
 			}
 		}
 	}
@@ -55,7 +78,14 @@ func loadGo17Types() {
 			(*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off)
 			typ := obj.(reflect.Type)
 			if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
-				types[typ.Elem().String()] = typ.Elem()
+				loadedType := typ.Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
 			}
 		}
 	}
@@ -68,5 +98,16 @@ type emptyInterface struct {
 
 // TypeByName return the type by its name, just like Class.forName in java
 func TypeByName(typeName string) Type {
+	initOnce.Do(discoverTypes)
 	return Type2(types[typeName])
 }
+
+// TypeByPackageName return the type by its package and name
+func TypeByPackageName(pkgPath string, name string) Type {
+	initOnce.Do(discoverTypes)
+	pkgTypes := packages[pkgPath]
+	if pkgTypes == nil {
+		return nil
+	}
+	return Type2(pkgTypes[name])
+}
diff --git a/unsafe_array.go b/unsafe_array.go
index 924b026..76cbdba 100644
--- a/unsafe_array.go
+++ b/unsafe_array.go
@@ -1,8 +1,8 @@
 package reflect2
 
 import (
-	"unsafe"
 	"reflect"
+	"unsafe"
 )
 
 type UnsafeArrayType struct {
diff --git a/unsafe_eface.go b/unsafe_eface.go
index 446f420..805010f 100644
--- a/unsafe_eface.go
+++ b/unsafe_eface.go
@@ -1,8 +1,8 @@
 package reflect2
 
 import (
-	"unsafe"
 	"reflect"
+	"unsafe"
 )
 
 type eface struct {
@@ -56,4 +56,4 @@ func (type2 *UnsafeEFaceType) Indirect(obj interface{}) interface{} {
 
 func (type2 *UnsafeEFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
 	return *(*interface{})(ptr)
-}
\ No newline at end of file
+}
diff --git a/unsafe_iface.go b/unsafe_iface.go
index 8f451ca..b601955 100644
--- a/unsafe_iface.go
+++ b/unsafe_iface.go
@@ -1,8 +1,8 @@
 package reflect2
 
 import (
-	"unsafe"
 	"reflect"
+	"unsafe"
 )
 
 type iface struct {
@@ -61,4 +61,4 @@ func (type2 *UnsafeIFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool {
 		return true
 	}
 	return false
-}
\ No newline at end of file
+}
diff --git a/unsafe_link.go b/unsafe_link.go
index a25a5f4..57229c8 100644
--- a/unsafe_link.go
+++ b/unsafe_link.go
@@ -67,4 +67,4 @@ func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
 // the benefit is to surface this assumption at the call site.)
 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
 	return add(p, uintptr(i)*eltSize, "i < len")
-}
\ No newline at end of file
+}
diff --git a/unsafe_ptr.go b/unsafe_ptr.go
index 843724d..8e5ec9c 100644
--- a/unsafe_ptr.go
+++ b/unsafe_ptr.go
@@ -1,8 +1,8 @@
 package reflect2
 
 import (
-	"unsafe"
 	"reflect"
+	"unsafe"
 )
 
 type UnsafePtrType struct {
diff --git a/unsafe_slice.go b/unsafe_slice.go
index 5ce85af..1c6d876 100644
--- a/unsafe_slice.go
+++ b/unsafe_slice.go
@@ -1,8 +1,8 @@
 package reflect2
 
 import (
-	"unsafe"
 	"reflect"
+	"unsafe"
 )
 
 // sliceHeader is a safe version of SliceHeader used within this package.
diff --git a/unsafe_struct.go b/unsafe_struct.go
index f91ef17..804d916 100644
--- a/unsafe_struct.go
+++ b/unsafe_struct.go
@@ -56,4 +56,4 @@ func (type2 *UnsafeStructType) FieldByNameFunc(match func(string) bool) StructFi
 		panic("field match condition not found in " + type2.Type.String())
 	}
 	return newUnsafeStructField(type2, structField)
-}
\ No newline at end of file
+}
diff --git a/unsafe_type.go b/unsafe_type.go
index e7ad4a6..1394171 100644
--- a/unsafe_type.go
+++ b/unsafe_type.go
@@ -1,8 +1,8 @@
 package reflect2
 
 import (
-	"unsafe"
 	"reflect"
+	"unsafe"
 )
 
 type unsafeType struct {
@@ -15,7 +15,7 @@ func newUnsafeType(cfg *frozenConfig, type1 reflect.Type) *unsafeType {
 	return &unsafeType{
 		safeType: safeType{
 			Type: type1,
-			cfg: cfg,
+			cfg:  cfg,
 		},
 		rtype:    unpackEFace(type1).data,
 		ptrRType: unpackEFace(reflect.PtrTo(type1)).data,