Move tests from test_issues.cpp/py into appropriate files
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index d40c25a..be223f5 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -40,7 +40,6 @@
   test_eval.cpp
   test_exceptions.cpp
   test_inheritance.cpp
-  test_issues.cpp
   test_kwargs_and_defaults.cpp
   test_methods_and_attributes.cpp
   test_modules.cpp
@@ -59,7 +58,7 @@
 )
 
 # Invoking cmake with something like:
-#     cmake -DPYBIND11_TEST_OVERRIDE="test_issues.cpp;test_picking.cpp" ..
+#     cmake -DPYBIND11_TEST_OVERRIDE="test_callbacks.cpp;test_picking.cpp" ..
 # lets you override the tests that get compiled and run.  You can restore to all tests with:
 #     cmake -DPYBIND11_TEST_OVERRIDE= ..
 if (PYBIND11_TEST_OVERRIDE)
diff --git a/tests/test_copy_move.cpp b/tests/test_copy_move.cpp
index 90ca6da..e80cdb8 100644
--- a/tests/test_copy_move.cpp
+++ b/tests/test_copy_move.cpp
@@ -187,4 +187,23 @@
         static PrivateOpNew x{};
         return x;
     }, py::return_value_policy::reference);
+
+    // #389: rvp::move should fall-through to copy on non-movable objects
+    struct MoveIssue1 {
+        int v;
+        MoveIssue1(int v) : v{v} {}
+        MoveIssue1(const MoveIssue1 &c) = default;
+        MoveIssue1(MoveIssue1 &&) = delete;
+    };
+
+    struct MoveIssue2 {
+        int v;
+        MoveIssue2(int v) : v{v} {}
+        MoveIssue2(MoveIssue2 &&) = default;
+    };
+
+    py::class_<MoveIssue1>(m, "MoveIssue1").def(py::init<int>()).def_readwrite("value", &MoveIssue1::v);
+    py::class_<MoveIssue2>(m, "MoveIssue2").def(py::init<int>()).def_readwrite("value", &MoveIssue2::v);
+    m.def("get_moveissue1", [](int i) { return new MoveIssue1(i); }, py::return_value_policy::move);
+    m.def("get_moveissue2", [](int i) { return MoveIssue2(i); }, py::return_value_policy::move);
 });
diff --git a/tests/test_copy_move.py b/tests/test_copy_move.py
index 386fce7..452f6fb 100644
--- a/tests/test_copy_move.py
+++ b/tests/test_copy_move.py
@@ -109,3 +109,13 @@
     assert "the object is neither movable nor copyable" in str(excinfo.value)
 
     assert m.private_op_new_reference().value == 1
+
+
+def test_move_fallback():
+    """#389: rvp::move should fall-through to copy on non-movable objects"""
+    from pybind11_tests import get_moveissue1, get_moveissue2
+
+    m2 = get_moveissue2(2)
+    assert m2.value == 2
+    m1 = get_moveissue1(1)
+    assert m1.value == 1
diff --git a/tests/test_inheritance.cpp b/tests/test_inheritance.cpp
index c19f58d..6129b3f 100644
--- a/tests/test_inheritance.cpp
+++ b/tests/test_inheritance.cpp
@@ -120,4 +120,24 @@
         py::class_<MismatchBase2>(m, "MismatchBase2");
         py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>, MismatchBase2>(m, "MismatchDerived2");
     });
+
+    // #511: problem with inheritance + overwritten def_static
+    struct MyBase {
+        static std::unique_ptr<MyBase> make() {
+            return std::unique_ptr<MyBase>(new MyBase());
+        }
+    };
+
+    struct MyDerived : MyBase {
+        static std::unique_ptr<MyDerived> make() {
+            return std::unique_ptr<MyDerived>(new MyDerived());
+        }
+    };
+
+    py::class_<MyBase>(m, "MyBase")
+        .def_static("make", &MyBase::make);
+
+    py::class_<MyDerived, MyBase>(m, "MyDerived")
+        .def_static("make", &MyDerived::make)
+        .def_static("make2", &MyDerived::make);
 });
diff --git a/tests/test_inheritance.py b/tests/test_inheritance.py
index d1f537d..40630ae 100644
--- a/tests/test_inheritance.py
+++ b/tests/test_inheritance.py
@@ -76,3 +76,16 @@
     assert str(excinfo.value) == ("generic_type: type \"MismatchDerived2\" has a "
                                   "non-default holder type while its base "
                                   "\"MismatchBase2\" does not")
+
+
+def test_inheritance_override_def_static():
+    """#511: problem with inheritance + overwritten def_static"""
+    from pybind11_tests import MyBase, MyDerived
+
+    b = MyBase.make()
+    d1 = MyDerived.make2()
+    d2 = MyDerived.make()
+
+    assert isinstance(b, MyBase)
+    assert isinstance(d1, MyDerived)
+    assert isinstance(d2, MyDerived)
diff --git a/tests/test_issues.cpp b/tests/test_issues.cpp
deleted file mode 100644
index 6d88d9a..0000000
--- a/tests/test_issues.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
-    tests/test_issues.cpp -- collection of testcases for miscellaneous issues
-
-    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
-
-    All rights reserved. Use of this source code is governed by a
-    BSD-style license that can be found in the LICENSE file.
-*/
-
-#include "pybind11_tests.h"
-#include "constructor_stats.h"
-#include <pybind11/stl.h>
-#include <pybind11/operators.h>
-#include <pybind11/complex.h>
-
-#define TRACKERS(CLASS) CLASS() { print_default_created(this); } ~CLASS() { print_destroyed(this); }
-struct NestABase { int value = -2; TRACKERS(NestABase) };
-struct NestA : NestABase { int value = 3; NestA& operator+=(int i) { value += i; return *this; } TRACKERS(NestA) };
-struct NestB { NestA a; int value = 4; NestB& operator-=(int i) { value -= i; return *this; } TRACKERS(NestB) };
-struct NestC { NestB b; int value = 5; NestC& operator*=(int i) { value *= i; return *this; } TRACKERS(NestC) };
-
-/// #393
-class OpTest1 {};
-class OpTest2 {};
-
-OpTest1 operator+(const OpTest1 &, const OpTest1 &) {
-    py::print("Add OpTest1 with OpTest1");
-    return OpTest1();
-}
-OpTest2 operator+(const OpTest2 &, const OpTest2 &) {
-    py::print("Add OpTest2 with OpTest2");
-    return OpTest2();
-}
-OpTest2 operator+(const OpTest2 &, const OpTest1 &) {
-    py::print("Add OpTest2 with OpTest1");
-    return OpTest2();
-}
-
-// #461
-class Dupe1 {
-public:
-    Dupe1(int v) : v_{v} {}
-    int get_value() const { return v_; }
-private:
-    int v_;
-};
-class Dupe2 {};
-class Dupe3 {};
-class DupeException : public std::runtime_error {};
-
-// #478
-template <typename T> class custom_unique_ptr {
-public:
-    custom_unique_ptr() { print_default_created(this); }
-    custom_unique_ptr(T *ptr) : _ptr{ptr} { print_created(this, ptr); }
-    custom_unique_ptr(custom_unique_ptr<T> &&move) : _ptr{move._ptr} { move._ptr = nullptr; print_move_created(this); }
-    custom_unique_ptr &operator=(custom_unique_ptr<T> &&move) { print_move_assigned(this); if (_ptr) destruct_ptr(); _ptr = move._ptr; move._ptr = nullptr; return *this; }
-    custom_unique_ptr(const custom_unique_ptr<T> &) = delete;
-    void operator=(const custom_unique_ptr<T> &copy) = delete;
-    ~custom_unique_ptr() { print_destroyed(this); if (_ptr) destruct_ptr(); }
-private:
-    T *_ptr = nullptr;
-    void destruct_ptr() { delete _ptr; }
-};
-PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>);
-
-/// Issue #528: templated constructor
-struct TplConstrClass {
-    template <typename T> TplConstrClass(const T &arg) : str{arg} {}
-    std::string str;
-    bool operator==(const TplConstrClass &t) const { return t.str == str; }
-};
-namespace std {
-template <> struct hash<TplConstrClass> { size_t operator()(const TplConstrClass &t) const { return std::hash<std::string>()(t.str); } };
-}
-
-void init_issues(py::module &m) {
-    py::module m2 = m.def_submodule("issues");
-
-    // #137: const char* isn't handled properly
-    m2.def("print_cchar", [](const char *s) { return std::string(s); });
-
-    // #150: char bindings broken
-    m2.def("print_char", [](char c) { return std::string(1, c); });
-
-    // #159: virtual function dispatch has problems with similar-named functions
-    struct Base { virtual std::string dispatch() const {
-        /* for some reason MSVC2015 can't compile this if the function is pure virtual */
-        return {};
-    }; };
-
-    struct DispatchIssue : Base {
-        virtual std::string dispatch() const {
-            PYBIND11_OVERLOAD_PURE(std::string, Base, dispatch, /* no arguments */);
-        }
-    };
-
-    py::class_<Base, DispatchIssue>(m2, "DispatchIssue")
-        .def(py::init<>())
-        .def("dispatch", &Base::dispatch);
-
-    m2.def("dispatch_issue_go", [](const Base * b) { return b->dispatch(); });
-
-    struct Placeholder { int i; Placeholder(int i) : i(i) { } };
-
-    py::class_<Placeholder>(m2, "Placeholder")
-        .def(py::init<int>())
-        .def("__repr__", [](const Placeholder &p) { return "Placeholder[" + std::to_string(p.i) + "]"; });
-
-    // #181: iterator passthrough did not compile
-    m2.def("iterator_passthrough", [](py::iterator s) -> py::iterator {
-        return py::make_iterator(std::begin(s), std::end(s));
-    });
-
-    // #187: issue involving std::shared_ptr<> return value policy & garbage collection
-    struct ElementBase { virtual void foo() { } /* Force creation of virtual table */ };
-    struct ElementA : ElementBase {
-        ElementA(int v) : v(v) { }
-        int value() { return v; }
-        int v;
-    };
-
-    struct ElementList {
-        void add(std::shared_ptr<ElementBase> e) { l.push_back(e); }
-        std::vector<std::shared_ptr<ElementBase>> l;
-    };
-
-    py::class_<ElementBase, std::shared_ptr<ElementBase>> (m2, "ElementBase");
-
-    py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(m2, "ElementA")
-        .def(py::init<int>())
-        .def("value", &ElementA::value);
-
-    py::class_<ElementList, std::shared_ptr<ElementList>>(m2, "ElementList")
-        .def(py::init<>())
-        .def("add", &ElementList::add)
-        .def("get", [](ElementList &el) {
-            py::list list;
-            for (auto &e : el.l)
-                list.append(py::cast(e));
-            return list;
-        });
-
-    // (no id): should not be able to pass 'None' to a reference argument
-    m2.def("get_element", [](ElementA &el) { return el.value(); });
-
-    // (no id): don't cast doubles to ints
-    m2.def("expect_float", [](float f) { return f; });
-    m2.def("expect_int", [](int i) { return i; });
-
-    try {
-        py::class_<Placeholder>(m2, "Placeholder");
-        throw std::logic_error("Expected an exception!");
-    } catch (std::runtime_error &) {
-        /* All good */
-    }
-
-    // Issue #283: __str__ called on uninitialized instance when constructor arguments invalid
-    class StrIssue {
-    public:
-        StrIssue(int i) : val{i} {}
-        StrIssue() : StrIssue(-1) {}
-        int value() const { return val; }
-    private:
-        int val;
-    };
-    py::class_<StrIssue> si(m2, "StrIssue");
-    si  .def(py::init<int>())
-        .def(py::init<>())
-        .def("__str__", [](const StrIssue &si) { return "StrIssue[" + std::to_string(si.value()) + "]"; })
-        ;
-
-    // Issue #328: first member in a class can't be used in operators
-    py::class_<NestABase>(m2, "NestABase").def(py::init<>()).def_readwrite("value", &NestABase::value);
-    py::class_<NestA>(m2, "NestA").def(py::init<>()).def(py::self += int())
-        .def("as_base", [](NestA &a) -> NestABase& { return (NestABase&) a; }, py::return_value_policy::reference_internal);
-    py::class_<NestB>(m2, "NestB").def(py::init<>()).def(py::self -= int()).def_readwrite("a", &NestB::a);
-    py::class_<NestC>(m2, "NestC").def(py::init<>()).def(py::self *= int()).def_readwrite("b", &NestC::b);
-    m2.def("get_NestA", [](const NestA &a) { return a.value; });
-    m2.def("get_NestB", [](const NestB &b) { return b.value; });
-    m2.def("get_NestC", [](const NestC &c) { return c.value; });
-
-    // Issue 389: r_v_p::move should fall-through to copy on non-movable objects
-    class MoveIssue1 {
-    public:
-        MoveIssue1(int v) : v{v} {}
-        MoveIssue1(const MoveIssue1 &c) { v = c.v; }
-        MoveIssue1(MoveIssue1 &&) = delete;
-        int v;
-    };
-    class MoveIssue2 {
-    public:
-        MoveIssue2(int v) : v{v} {}
-        MoveIssue2(MoveIssue2 &&) = default;
-        int v;
-    };
-    py::class_<MoveIssue1>(m2, "MoveIssue1").def(py::init<int>()).def_readwrite("value", &MoveIssue1::v);
-    py::class_<MoveIssue2>(m2, "MoveIssue2").def(py::init<int>()).def_readwrite("value", &MoveIssue2::v);
-    m2.def("get_moveissue1", [](int i) -> MoveIssue1 * { return new MoveIssue1(i); }, py::return_value_policy::move);
-    m2.def("get_moveissue2", [](int i) { return MoveIssue2(i); }, py::return_value_policy::move);
-
-    // Issues 392/397: overridding reference-returning functions
-    class OverrideTest {
-    public:
-        struct A { std::string value = "hi"; };
-        std::string v;
-        A a;
-        explicit OverrideTest(const std::string &v) : v{v} {}
-        virtual std::string str_value() { return v; }
-        virtual std::string &str_ref() { return v; }
-        virtual A A_value() { return a; }
-        virtual A &A_ref() { return a; }
-    };
-    class PyOverrideTest : public OverrideTest {
-    public:
-        using OverrideTest::OverrideTest;
-        std::string str_value() override { PYBIND11_OVERLOAD(std::string, OverrideTest, str_value); }
-        // Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
-        // to a python numeric value, since we only copy values in the numeric type caster:
-//      std::string &str_ref() override { PYBIND11_OVERLOAD(std::string &, OverrideTest, str_ref); }
-        // But we can work around it like this:
-    private:
-        std::string _tmp;
-        std::string str_ref_helper() { PYBIND11_OVERLOAD(std::string, OverrideTest, str_ref); }
-    public:
-        std::string &str_ref() override { return _tmp = str_ref_helper(); }
-
-        A A_value() override { PYBIND11_OVERLOAD(A, OverrideTest, A_value); }
-        A &A_ref() override { PYBIND11_OVERLOAD(A &, OverrideTest, A_ref); }
-    };
-    py::class_<OverrideTest::A>(m2, "OverrideTest_A")
-        .def_readwrite("value", &OverrideTest::A::value);
-    py::class_<OverrideTest, PyOverrideTest>(m2, "OverrideTest")
-        .def(py::init<const std::string &>())
-        .def("str_value", &OverrideTest::str_value)
-//      .def("str_ref", &OverrideTest::str_ref)
-        .def("A_value", &OverrideTest::A_value)
-        .def("A_ref", &OverrideTest::A_ref);
-
-    /// Issue 393: need to return NotSupported to ensure correct arithmetic operator behavior
-    py::class_<OpTest1>(m2, "OpTest1")
-        .def(py::init<>())
-        .def(py::self + py::self);
-
-    py::class_<OpTest2>(m2, "OpTest2")
-        .def(py::init<>())
-        .def(py::self + py::self)
-        .def("__add__", [](const OpTest2& c2, const OpTest1& c1) { return c2 + c1; })
-        .def("__radd__", [](const OpTest2& c2, const OpTest1& c1) { return c2 + c1; });
-
-    // Issue 388: Can't make iterators via make_iterator() with different r/v policies
-    static std::vector<int> list = { 1, 2, 3 };
-    m2.def("make_iterator_1", []() { return py::make_iterator<py::return_value_policy::copy>(list); });
-    m2.def("make_iterator_2", []() { return py::make_iterator<py::return_value_policy::automatic>(list); });
-
-    static std::vector<std::string> nothrows;
-    // Issue 461: registering two things with the same name:
-    py::class_<Dupe1>(m2, "Dupe1")
-        .def("get_value", &Dupe1::get_value)
-        ;
-    m2.def("dupe1_factory", [](int v) { return new Dupe1(v); });
-
-    py::class_<Dupe2>(m2, "Dupe2");
-    py::exception<DupeException>(m2, "DupeException");
-
-    try {
-        m2.def("Dupe1", [](int v) { return new Dupe1(v); });
-        nothrows.emplace_back("Dupe1");
-    }
-    catch (std::runtime_error &) {}
-    try {
-        py::class_<Dupe3>(m2, "dupe1_factory");
-        nothrows.emplace_back("dupe1_factory");
-    }
-    catch (std::runtime_error &) {}
-    try {
-        py::exception<Dupe3>(m2, "Dupe2");
-        nothrows.emplace_back("Dupe2");
-    }
-    catch (std::runtime_error &) {}
-    try {
-        m2.def("DupeException", []() { return 30; });
-        nothrows.emplace_back("DupeException1");
-    }
-    catch (std::runtime_error &) {}
-    try {
-        py::class_<DupeException>(m2, "DupeException");
-        nothrows.emplace_back("DupeException2");
-    }
-    catch (std::runtime_error &) {}
-    m2.def("dupe_exception_failures", []() {
-        py::list l;
-        for (auto &e : nothrows) l.append(py::cast(e));
-        return l;
-    });
-
-    /// Issue #471: shared pointer instance not dellocated
-    class SharedChild : public std::enable_shared_from_this<SharedChild> {
-    public:
-        SharedChild() { print_created(this); }
-        ~SharedChild() { print_destroyed(this); }
-    };
-
-    class SharedParent {
-    public:
-        SharedParent() : child(std::make_shared<SharedChild>()) { }
-        const SharedChild &get_child() const { return *child; }
-
-    private:
-        std::shared_ptr<SharedChild> child;
-    };
-
-    py::class_<SharedChild, std::shared_ptr<SharedChild>>(m, "SharedChild");
-    py::class_<SharedParent, std::shared_ptr<SharedParent>>(m, "SharedParent")
-        .def(py::init<>())
-        .def("get_child", &SharedParent::get_child, py::return_value_policy::reference);
-
-    /// Issue/PR #478: unique ptrs constructed and freed without destruction
-    class SpecialHolderObj {
-    public:
-        int val = 0;
-        SpecialHolderObj *ch = nullptr;
-        SpecialHolderObj(int v, bool make_child = true) : val{v}, ch{make_child ? new SpecialHolderObj(val+1, false) : nullptr}
-        { print_created(this, val); }
-        ~SpecialHolderObj() { delete ch; print_destroyed(this); }
-        SpecialHolderObj *child() { return ch; }
-    };
-
-    py::class_<SpecialHolderObj, custom_unique_ptr<SpecialHolderObj>>(m, "SpecialHolderObj")
-        .def(py::init<int>())
-        .def("child", &SpecialHolderObj::child, pybind11::return_value_policy::reference_internal)
-        .def_readwrite("val", &SpecialHolderObj::val)
-        .def_static("holder_cstats", &ConstructorStats::get<custom_unique_ptr<SpecialHolderObj>>,
-                py::return_value_policy::reference);
-
-    /// Issue #484: number conversion generates unhandled exceptions
-    m2.def("test_complex", [](float x) { py::print("{}"_s.format(x)); });
-    m2.def("test_complex", [](std::complex<float> x) { py::print("({}, {})"_s.format(x.real(), x.imag())); });
-
-    /// Issue #511: problem with inheritance + overwritten def_static
-    struct MyBase {
-        static std::unique_ptr<MyBase> make() {
-            return std::unique_ptr<MyBase>(new MyBase());
-        }
-    };
-
-    struct MyDerived : MyBase {
-        static std::unique_ptr<MyDerived> make() {
-            return std::unique_ptr<MyDerived>(new MyDerived());
-        }
-    };
-
-    py::class_<MyBase>(m2, "MyBase")
-        .def_static("make", &MyBase::make);
-
-    py::class_<MyDerived, MyBase>(m2, "MyDerived")
-        .def_static("make", &MyDerived::make)
-        .def_static("make2", &MyDerived::make);
-
-    py::dict d;
-    std::string bar = "bar";
-    d["str"] = bar;
-    d["num"] = 3.7;
-
-    /// Issue #528: templated constructor
-    m2.def("tpl_constr_vector", [](std::vector<TplConstrClass> &) {});
-    m2.def("tpl_constr_map", [](std::unordered_map<TplConstrClass, TplConstrClass> &) {});
-    m2.def("tpl_constr_set", [](std::unordered_set<TplConstrClass> &) {});
-#if defined(PYBIND11_HAS_OPTIONAL)
-    m2.def("tpl_constr_optional", [](std::optional<TplConstrClass> &) {});
-#elif defined(PYBIND11_HAS_EXP_OPTIONAL)
-    m2.def("tpl_constr_optional", [](std::experimental::optional<TplConstrClass> &) {});
-#endif
-}
-
-// MSVC workaround: trying to use a lambda here crashes MSVC
-test_initializer issues(&init_issues);
diff --git a/tests/test_issues.py b/tests/test_issues.py
deleted file mode 100644
index 08678cf..0000000
--- a/tests/test_issues.py
+++ /dev/null
@@ -1,243 +0,0 @@
-import pytest
-from pybind11_tests import ConstructorStats
-
-
-def test_regressions():
-    from pybind11_tests.issues import print_cchar, print_char
-
-    # #137: const char* isn't handled properly
-    assert print_cchar("const char *") == "const char *"
-    # #150: char bindings broken
-    assert print_char("c") == "c"
-
-
-def test_dispatch_issue(msg):
-    """#159: virtual function dispatch has problems with similar-named functions"""
-    from pybind11_tests.issues import DispatchIssue, dispatch_issue_go
-
-    class PyClass1(DispatchIssue):
-        def dispatch(self):
-            return "Yay.."
-
-    class PyClass2(DispatchIssue):
-        def dispatch(self):
-            with pytest.raises(RuntimeError) as excinfo:
-                super(PyClass2, self).dispatch()
-            assert msg(excinfo.value) == 'Tried to call pure virtual function "Base::dispatch"'
-
-            p = PyClass1()
-            return dispatch_issue_go(p)
-
-    b = PyClass2()
-    assert dispatch_issue_go(b) == "Yay.."
-
-
-def test_iterator_passthrough():
-    """#181: iterator passthrough did not compile"""
-    from pybind11_tests.issues import iterator_passthrough
-
-    assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15]
-
-
-def test_shared_ptr_gc():
-    """// #187: issue involving std::shared_ptr<> return value policy & garbage collection"""
-    from pybind11_tests.issues import ElementList, ElementA
-
-    el = ElementList()
-    for i in range(10):
-        el.add(ElementA(i))
-    pytest.gc_collect()
-    for i, v in enumerate(el.get()):
-        assert i == v.value()
-
-
-def test_no_id(msg):
-    from pybind11_tests.issues import get_element, expect_float, expect_int
-
-    with pytest.raises(TypeError) as excinfo:
-        get_element(None)
-    assert msg(excinfo.value) == """
-        get_element(): incompatible function arguments. The following argument types are supported:
-            1. (arg0: m.issues.ElementA) -> int
-
-        Invoked with: None
-    """
-
-    with pytest.raises(TypeError) as excinfo:
-        expect_int(5.2)
-    assert msg(excinfo.value) == """
-        expect_int(): incompatible function arguments. The following argument types are supported:
-            1. (arg0: int) -> int
-
-        Invoked with: 5.2
-    """
-    assert expect_float(12) == 12
-
-
-def test_str_issue(msg):
-    """Issue #283: __str__ called on uninitialized instance when constructor arguments invalid"""
-    from pybind11_tests.issues import StrIssue
-
-    assert str(StrIssue(3)) == "StrIssue[3]"
-
-    with pytest.raises(TypeError) as excinfo:
-        str(StrIssue("no", "such", "constructor"))
-    assert msg(excinfo.value) == """
-        __init__(): incompatible constructor arguments. The following argument types are supported:
-            1. m.issues.StrIssue(arg0: int)
-            2. m.issues.StrIssue()
-
-        Invoked with: 'no', 'such', 'constructor'
-    """
-
-
-def test_nested():
-    """ #328: first member in a class can't be used in operators"""
-    from pybind11_tests.issues import NestA, NestB, NestC, get_NestA, get_NestB, get_NestC
-
-    a = NestA()
-    b = NestB()
-    c = NestC()
-
-    a += 10
-    assert get_NestA(a) == 13
-    b.a += 100
-    assert get_NestA(b.a) == 103
-    c.b.a += 1000
-    assert get_NestA(c.b.a) == 1003
-    b -= 1
-    assert get_NestB(b) == 3
-    c.b -= 3
-    assert get_NestB(c.b) == 1
-    c *= 7
-    assert get_NestC(c) == 35
-
-    abase = a.as_base()
-    assert abase.value == -2
-    a.as_base().value += 44
-    assert abase.value == 42
-    assert c.b.a.as_base().value == -2
-    c.b.a.as_base().value += 44
-    assert c.b.a.as_base().value == 42
-
-    del c
-    pytest.gc_collect()
-    del a  # Should't delete while abase is still alive
-    pytest.gc_collect()
-
-    assert abase.value == 42
-    del abase, b
-    pytest.gc_collect()
-
-
-def test_move_fallback():
-    from pybind11_tests.issues import get_moveissue1, get_moveissue2
-    m2 = get_moveissue2(2)
-    assert m2.value == 2
-    m1 = get_moveissue1(1)
-    assert m1.value == 1
-
-
-def test_override_ref():
-    from pybind11_tests.issues import OverrideTest
-    o = OverrideTest("asdf")
-
-    # Not allowed (see associated .cpp comment)
-    # i = o.str_ref()
-    # assert o.str_ref() == "asdf"
-    assert o.str_value() == "asdf"
-
-    assert o.A_value().value == "hi"
-    a = o.A_ref()
-    assert a.value == "hi"
-    a.value = "bye"
-    assert a.value == "bye"
-
-
-def test_operators_notimplemented(capture):
-    from pybind11_tests.issues import OpTest1, OpTest2
-    with capture:
-        c1, c2 = OpTest1(), OpTest2()
-        c1 + c1
-        c2 + c2
-        c2 + c1
-        c1 + c2
-    assert capture == """
-        Add OpTest1 with OpTest1
-        Add OpTest2 with OpTest2
-        Add OpTest2 with OpTest1
-        Add OpTest2 with OpTest1
-    """
-
-
-def test_iterator_rvpolicy():
-    """ Issue 388: Can't make iterators via make_iterator() with different r/v policies """
-    from pybind11_tests.issues import make_iterator_1
-    from pybind11_tests.issues import make_iterator_2
-
-    assert list(make_iterator_1()) == [1, 2, 3]
-    assert list(make_iterator_2()) == [1, 2, 3]
-    assert not isinstance(make_iterator_1(), type(make_iterator_2()))
-
-
-def test_dupe_assignment():
-    """ Issue 461: overwriting a class with a function """
-    from pybind11_tests.issues import dupe_exception_failures
-    assert dupe_exception_failures() == []
-
-
-def test_enable_shared_from_this_with_reference_rvp():
-    """ Issue #471: shared pointer instance not dellocated """
-    from pybind11_tests import SharedParent, SharedChild
-
-    parent = SharedParent()
-    child = parent.get_child()
-
-    cstats = ConstructorStats.get(SharedChild)
-    assert cstats.alive() == 1
-    del child, parent
-    assert cstats.alive() == 0
-
-
-def test_non_destructed_holders():
-    """ Issue #478: unique ptrs constructed and freed without destruction """
-    from pybind11_tests import SpecialHolderObj
-
-    a = SpecialHolderObj(123)
-    b = a.child()
-
-    assert a.val == 123
-    assert b.val == 124
-
-    cstats = SpecialHolderObj.holder_cstats()
-    assert cstats.alive() == 1
-    del b
-    assert cstats.alive() == 1
-    del a
-    assert cstats.alive() == 0
-
-
-def test_complex_cast(capture):
-    """ Issue #484: number conversion generates unhandled exceptions """
-    from pybind11_tests.issues import test_complex
-
-    with capture:
-        test_complex(1)
-        test_complex(2j)
-
-    assert capture == """
-        1.0
-        (0.0, 2.0)
-    """
-
-
-def test_inheritance_override_def_static():
-    from pybind11_tests.issues import MyBase, MyDerived
-
-    b = MyBase.make()
-    d1 = MyDerived.make2()
-    d2 = MyDerived.make()
-
-    assert isinstance(b, MyBase)
-    assert isinstance(d1, MyDerived)
-    assert isinstance(d2, MyDerived)
diff --git a/tests/test_methods_and_attributes.cpp b/tests/test_methods_and_attributes.cpp
index 81b665b..670f6c3 100644
--- a/tests/test_methods_and_attributes.cpp
+++ b/tests/test_methods_and_attributes.cpp
@@ -170,6 +170,13 @@
 int none4(std::shared_ptr<NoneTester> *obj) { return obj && *obj ? (*obj)->answer : -1; }
 int none5(std::shared_ptr<NoneTester> obj) { return obj ? obj->answer : -1; }
 
+struct StrIssue {
+    int val = -1;
+
+    StrIssue() = default;
+    StrIssue(int i) : val{i} {}
+};
+
 test_initializer methods_and_attributes([](py::module &m) {
     py::class_<ExampleMandA> emna(m, "ExampleMandA");
     emna.def(py::init<>())
@@ -315,6 +322,8 @@
 
     m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
     m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
+    m.def("ints_preferred", [](int i) { return i / 2; }, py::arg("i"));
+    m.def("ints_only", [](int i) { return i / 2; }, py::arg("i").noconvert());
 
     /// Issue/PR #648: bad arg default debugging output
 #if !defined(NDEBUG)
@@ -344,4 +353,11 @@
     m.def("ok_none4", &none4, py::arg().none(true));
     m.def("ok_none5", &none5);
 
+    // Issue #283: __str__ called on uninitialized instance when constructor arguments invalid
+    py::class_<StrIssue>(m, "StrIssue")
+        .def(py::init<int>())
+        .def(py::init<>())
+        .def("__str__", [](const StrIssue &si) {
+            return "StrIssue[" + std::to_string(si.val) + "]"; }
+        );
 });
diff --git a/tests/test_methods_and_attributes.py b/tests/test_methods_and_attributes.py
index 3ec3eb7..95049cf 100644
--- a/tests/test_methods_and_attributes.py
+++ b/tests/test_methods_and_attributes.py
@@ -304,9 +304,9 @@
 
 
 def test_noconvert_args(msg):
-    from pybind11_tests import ArgInspector, arg_inspect_func, floats_only, floats_preferred
+    import pybind11_tests as m
 
-    a = ArgInspector()
+    a = m.ArgInspector()
     assert msg(a.f("hi")) == """
         loading ArgInspector1 argument WITH conversion allowed.  Argument value = hi
     """
@@ -330,15 +330,15 @@
     """
     assert (a.h("arg 1") ==
             "loading ArgInspector2 argument WITHOUT conversion allowed.  Argument value = arg 1")
-    assert msg(arg_inspect_func("A1", "A2")) == """
+    assert msg(m.arg_inspect_func("A1", "A2")) == """
         loading ArgInspector2 argument WITH conversion allowed.  Argument value = A1
         loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = A2
     """
 
-    assert floats_preferred(4) == 2.0
-    assert floats_only(4.0) == 2.0
+    assert m.floats_preferred(4) == 2.0
+    assert m.floats_only(4.0) == 2.0
     with pytest.raises(TypeError) as excinfo:
-        floats_only(4)
+        m.floats_only(4)
     assert msg(excinfo.value) == """
         floats_only(): incompatible function arguments. The following argument types are supported:
             1. (f: float) -> float
@@ -346,6 +346,27 @@
         Invoked with: 4
     """
 
+    assert m.ints_preferred(4) == 2
+    assert m.ints_preferred(True) == 0
+    with pytest.raises(TypeError) as excinfo:
+        m.ints_preferred(4.0)
+    assert msg(excinfo.value) == """
+        ints_preferred(): incompatible function arguments. The following argument types are supported:
+            1. (i: int) -> int
+
+        Invoked with: 4.0
+    """  # noqa: E501 line too long
+
+    assert m.ints_only(4) == 2
+    with pytest.raises(TypeError) as excinfo:
+        m.ints_only(4.0)
+    assert msg(excinfo.value) == """
+        ints_only(): incompatible function arguments. The following argument types are supported:
+            1. (i: int) -> int
+
+        Invoked with: 4.0
+    """
+
 
 def test_bad_arg_default(msg):
     from pybind11_tests import debug_enabled, bad_arg_def_named, bad_arg_def_unnamed
@@ -371,7 +392,7 @@
     )
 
 
-def test_accepts_none():
+def test_accepts_none(msg):
     from pybind11_tests import (NoneTester,
                                 no_none1, no_none2, no_none3, no_none4, no_none5,
                                 ok_none1, ok_none2, ok_none3, ok_none4, ok_none5)
@@ -407,9 +428,32 @@
     # The first one still raises because you can't pass None as a lvalue reference arg:
     with pytest.raises(TypeError) as excinfo:
         assert ok_none1(None) == -1
-    assert "incompatible function arguments" in str(excinfo.value)
+    assert msg(excinfo.value) == """
+        ok_none1(): incompatible function arguments. The following argument types are supported:
+            1. (arg0: m.NoneTester) -> int
+
+        Invoked with: None
+    """
+
     # The rest take the argument as pointer or holder, and accept None:
     assert ok_none2(None) == -1
     assert ok_none3(None) == -1
     assert ok_none4(None) == -1
     assert ok_none5(None) == -1
+
+
+def test_str_issue(msg):
+    """#283: __str__ called on uninitialized instance when constructor arguments invalid"""
+    from pybind11_tests import StrIssue
+
+    assert str(StrIssue(3)) == "StrIssue[3]"
+
+    with pytest.raises(TypeError) as excinfo:
+        str(StrIssue("no", "such", "constructor"))
+    assert msg(excinfo.value) == """
+        __init__(): incompatible constructor arguments. The following argument types are supported:
+            1. m.StrIssue(arg0: int)
+            2. m.StrIssue()
+
+        Invoked with: 'no', 'such', 'constructor'
+    """
diff --git a/tests/test_modules.cpp b/tests/test_modules.cpp
index 50c7d84..555ae07 100644
--- a/tests/test_modules.cpp
+++ b/tests/test_modules.cpp
@@ -55,4 +55,47 @@
         .def_readwrite("a2", &B::a2);
 
     m.attr("OD") = py::module::import("collections").attr("OrderedDict");
+
+    // Registering two things with the same name
+    m.def("duplicate_registration", []() {
+        class Dupe1 { };
+        class Dupe2 { };
+        class Dupe3 { };
+        class DupeException { };
+
+        auto dm = py::module("dummy");
+        auto failures = py::list();
+
+        py::class_<Dupe1>(dm, "Dupe1");
+        py::class_<Dupe2>(dm, "Dupe2");
+        dm.def("dupe1_factory", []() { return Dupe1(); });
+        py::exception<DupeException>(dm, "DupeException");
+
+        try {
+            py::class_<Dupe1>(dm, "Dupe1");
+            failures.append("Dupe1 class");
+        } catch (std::runtime_error &) {}
+        try {
+            dm.def("Dupe1", []() { return Dupe1(); });
+            failures.append("Dupe1 function");
+        } catch (std::runtime_error &) {}
+        try {
+            py::class_<Dupe3>(dm, "dupe1_factory");
+            failures.append("dupe1_factory");
+        } catch (std::runtime_error &) {}
+        try {
+            py::exception<Dupe3>(dm, "Dupe2");
+            failures.append("Dupe2");
+        } catch (std::runtime_error &) {}
+        try {
+            dm.def("DupeException", []() { return 30; });
+            failures.append("DupeException1");
+        } catch (std::runtime_error &) {}
+        try {
+            py::class_<DupeException>(dm, "DupeException");
+            failures.append("DupeException2");
+        } catch (std::runtime_error &) {}
+
+        return failures;
+    });
 });
diff --git a/tests/test_modules.py b/tests/test_modules.py
index 2a2c794..1cb177f 100644
--- a/tests/test_modules.py
+++ b/tests/test_modules.py
@@ -61,3 +61,10 @@
 
     assert pybind11_tests.__doc__ == "pybind11 test module"
     assert pydoc.text.docmodule(pybind11_tests)
+
+
+def test_duplicate_registration():
+    """Registering two things with the same name"""
+    from pybind11_tests import duplicate_registration
+
+    assert duplicate_registration() == []
diff --git a/tests/test_operator_overloading.cpp b/tests/test_operator_overloading.cpp
index 4e868d9..cb22b12 100644
--- a/tests/test_operator_overloading.cpp
+++ b/tests/test_operator_overloading.cpp
@@ -56,7 +56,38 @@
     float x, y;
 };
 
-test_initializer operator_overloading([](py::module &m) {
+class C1 { };
+class C2 { };
+
+int operator+(const C1 &, const C1 &) { return 11; }
+int operator+(const C2 &, const C2 &) { return 22; }
+int operator+(const C2 &, const C1 &) { return 21; }
+int operator+(const C1 &, const C2 &) { return 12; }
+
+struct NestABase {
+    int value = -2;
+};
+
+struct NestA : NestABase {
+    int value = 3;
+    NestA& operator+=(int i) { value += i; return *this; }
+};
+
+struct NestB {
+    NestA a;
+    int value = 4;
+    NestB& operator-=(int i) { value -= i; return *this; }
+};
+
+struct NestC {
+    NestB b;
+    int value = 5;
+    NestC& operator*=(int i) { value *= i; return *this; }
+};
+
+test_initializer operator_overloading([](py::module &pm) {
+    auto m = pm.def_submodule("operators");
+
     py::class_<Vector2>(m, "Vector2")
         .def(py::init<float, float>())
         .def(py::self + py::self)
@@ -81,4 +112,41 @@
         ;
 
     m.attr("Vector") = m.attr("Vector2");
+
+    // #393: need to return NotSupported to ensure correct arithmetic operator behavior
+    py::class_<C1>(m, "C1")
+        .def(py::init<>())
+        .def(py::self + py::self);
+
+    py::class_<C2>(m, "C2")
+        .def(py::init<>())
+        .def(py::self + py::self)
+        .def("__add__", [](const C2& c2, const C1& c1) { return c2 + c1; })
+        .def("__radd__", [](const C2& c2, const C1& c1) { return c1 + c2; });
+
+    // #328: first member in a class can't be used in operators
+    py::class_<NestABase>(m, "NestABase")
+        .def(py::init<>())
+        .def_readwrite("value", &NestABase::value);
+
+    py::class_<NestA>(m, "NestA")
+        .def(py::init<>())
+        .def(py::self += int())
+        .def("as_base", [](NestA &a) -> NestABase& {
+            return (NestABase&) a;
+        }, py::return_value_policy::reference_internal);
+
+    py::class_<NestB>(m, "NestB")
+        .def(py::init<>())
+        .def(py::self -= int())
+        .def_readwrite("a", &NestB::a);
+
+    py::class_<NestC>(m, "NestC")
+        .def(py::init<>())
+        .def(py::self *= int())
+        .def_readwrite("b", &NestC::b);
+
+    m.def("get_NestA", [](const NestA &a) { return a.value; });
+    m.def("get_NestB", [](const NestB &b) { return b.value; });
+    m.def("get_NestC", [](const NestC &c) { return c.value; });
 });
diff --git a/tests/test_operator_overloading.py b/tests/test_operator_overloading.py
index dd37c34..63dd546 100644
--- a/tests/test_operator_overloading.py
+++ b/tests/test_operator_overloading.py
@@ -1,5 +1,9 @@
+import pytest
+from pybind11_tests import ConstructorStats
+
+
 def test_operator_overloading():
-    from pybind11_tests import Vector2, Vector, ConstructorStats
+    from pybind11_tests.operators import Vector2, Vector
 
     v1 = Vector2(1, 2)
     v2 = Vector(3, -1)
@@ -51,3 +55,53 @@
     assert cstats.move_constructions >= 10
     assert cstats.copy_assignments == 0
     assert cstats.move_assignments == 0
+
+
+def test_operators_notimplemented():
+    """#393: need to return NotSupported to ensure correct arithmetic operator behavior"""
+    from pybind11_tests.operators import C1, C2
+
+    c1, c2 = C1(), C2()
+    assert c1 + c1 == 11
+    assert c2 + c2 == 22
+    assert c2 + c1 == 21
+    assert c1 + c2 == 12
+
+
+def test_nested():
+    """#328: first member in a class can't be used in operators"""
+    from pybind11_tests.operators import NestA, NestB, NestC, get_NestA, get_NestB, get_NestC
+
+    a = NestA()
+    b = NestB()
+    c = NestC()
+
+    a += 10
+    assert get_NestA(a) == 13
+    b.a += 100
+    assert get_NestA(b.a) == 103
+    c.b.a += 1000
+    assert get_NestA(c.b.a) == 1003
+    b -= 1
+    assert get_NestB(b) == 3
+    c.b -= 3
+    assert get_NestB(c.b) == 1
+    c *= 7
+    assert get_NestC(c) == 35
+
+    abase = a.as_base()
+    assert abase.value == -2
+    a.as_base().value += 44
+    assert abase.value == 42
+    assert c.b.a.as_base().value == -2
+    c.b.a.as_base().value += 44
+    assert c.b.a.as_base().value == 42
+
+    del c
+    pytest.gc_collect()
+    del a  # Should't delete while abase is still alive
+    pytest.gc_collect()
+
+    assert abase.value == 42
+    del abase, b
+    pytest.gc_collect()
diff --git a/tests/test_python_types.cpp b/tests/test_python_types.cpp
index d130af6..46a23ee 100644
--- a/tests/test_python_types.cpp
+++ b/tests/test_python_types.cpp
@@ -11,6 +11,7 @@
 #include "pybind11_tests.h"
 #include "constructor_stats.h"
 #include <pybind11/stl.h>
+#include <pybind11/complex.h>
 
 #ifdef _WIN32
 #  include <io.h>
@@ -215,6 +216,17 @@
     return r;
 };
 
+/// Issue #528: templated constructor
+struct TplCtorClass {
+    template <typename T> TplCtorClass(const T &) { }
+    bool operator==(const TplCtorClass &) const { return true; }
+};
+
+namespace std {
+    template <>
+    struct hash<TplCtorClass> { size_t operator()(const TplCtorClass &) const { return 0; } };
+}
+
 test_initializer python_types([](py::module &m) {
     /* No constructor is explicitly defined below. An exception is raised when
        trying to construct it directly from Python */
@@ -501,6 +513,8 @@
         );
     });
 
+    m.def("string_roundtrip", [](const char *s) { return s; });
+
     // Some test characters in utf16 and utf32 encodings.  The last one (the 𝐀) contains a null byte
     char32_t a32 = 0x61 /*a*/, z32 = 0x7a /*z*/, ib32 = 0x203d /*‽*/, cake32 = 0x1f382 /*🎂*/,              mathbfA32 = 0x1d400 /*𝐀*/;
     char16_t b16 = 0x62 /*b*/, z16 = 0x7a,       ib16 = 0x203d,       cake16_1 = 0xd83c, cake16_2 = 0xdf82, mathbfA16_1 = 0xd835, mathbfA16_2 = 0xdc00;
@@ -661,6 +675,19 @@
         return l;
     });
 
+    /// Issue #484: number conversion generates unhandled exceptions
+    m.def("test_complex", [](float x) { return "{}"_s.format(x); });
+    m.def("test_complex", [](std::complex<float> x) { return "({}, {})"_s.format(x.real(), x.imag()); });
+
+    /// Issue #528: templated constructor
+    m.def("tpl_ctor_vector", [](std::vector<TplCtorClass> &) {});
+    m.def("tpl_ctor_map", [](std::unordered_map<TplCtorClass, TplCtorClass> &) {});
+    m.def("tpl_ctor_set", [](std::unordered_set<TplCtorClass> &) {});
+#if defined(PYBIND11_HAS_OPTIONAL)
+    m.def("tpl_constr_optional", [](std::optional<TplCtorClass> &) {});
+#elif defined(PYBIND11_HAS_EXP_OPTIONAL)
+    m.def("tpl_constr_optional", [](std::experimental::optional<TplCtorClass> &) {});
+#endif
 });
 
 #if defined(_MSC_VER)
diff --git a/tests/test_python_types.py b/tests/test_python_types.py
index 2af9432..7932602 100644
--- a/tests/test_python_types.py
+++ b/tests/test_python_types.py
@@ -452,6 +452,12 @@
     assert z['l'] == [3, 6, 9, 12, 15]
 
 
+def test_simple_string():
+    from pybind11_tests import string_roundtrip
+
+    assert string_roundtrip("const char *") == "const char *"
+
+
 def test_unicode_conversion():
     """Tests unicode conversion and error reporting."""
     import pybind11_tests
@@ -699,3 +705,11 @@
 
     assert refwrap_iiw(IncrIntWrapper(5)) == 5
     assert refwrap_call_iiw(IncrIntWrapper(10), refwrap_iiw) == [10, 10, 10, 10]
+
+
+def test_complex_cast():
+    """#484: number conversion generates unhandled exceptions"""
+    from pybind11_tests import test_complex
+
+    assert test_complex(1) == "1.0"
+    assert test_complex(2j) == "(0.0, 2.0)"
diff --git a/tests/test_sequences_and_iterators.cpp b/tests/test_sequences_and_iterators.cpp
index c2051fa..89fde8f 100644
--- a/tests/test_sequences_and_iterators.cpp
+++ b/tests/test_sequences_and_iterators.cpp
@@ -351,4 +351,14 @@
     m.def("tuple_iterator", [](py::tuple x) { return test_random_access_iterator(x); });
     m.def("list_iterator", [](py::list x) { return test_random_access_iterator(x); });
     m.def("sequence_iterator", [](py::sequence x) { return test_random_access_iterator(x); });
+
+    // #181: iterator passthrough did not compile
+    m.def("iterator_passthrough", [](py::iterator s) -> py::iterator {
+        return py::make_iterator(std::begin(s), std::end(s));
+    });
+
+    // #388: Can't make iterators via make_iterator() with different r/v policies
+    static std::vector<int> list = { 1, 2, 3 };
+    m.def("make_iterator_1", []() { return py::make_iterator<py::return_value_policy::copy>(list); });
+    m.def("make_iterator_2", []() { return py::make_iterator<py::return_value_policy::automatic>(list); });
 });
diff --git a/tests/test_sequences_and_iterators.py b/tests/test_sequences_and_iterators.py
index e04c579..012e97d 100644
--- a/tests/test_sequences_and_iterators.py
+++ b/tests/test_sequences_and_iterators.py
@@ -147,3 +147,20 @@
     assert all(m.tuple_iterator(tuple(r)))
     assert all(m.list_iterator(list(r)))
     assert all(m.sequence_iterator(r))
+
+
+def test_iterator_passthrough():
+    """#181: iterator passthrough did not compile"""
+    from pybind11_tests.sequences_and_iterators import iterator_passthrough
+
+    assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15]
+
+
+def test_iterator_rvp():
+    """#388: Can't make iterators via make_iterator() with different r/v policies """
+    import pybind11_tests.sequences_and_iterators as m
+
+    assert list(m.make_iterator_1()) == [1, 2, 3]
+    assert list(m.make_iterator_2()) == [1, 2, 3]
+    assert not isinstance(m.make_iterator_1(), type(m.make_iterator_2()))
+
diff --git a/tests/test_smart_ptr.cpp b/tests/test_smart_ptr.cpp
index 1ece3d1..91239e8 100644
--- a/tests/test_smart_ptr.cpp
+++ b/tests/test_smart_ptr.cpp
@@ -259,6 +259,18 @@
 
 PYBIND11_DECLARE_HOLDER_TYPE(T, CustomUniquePtr<T>);
 
+struct ElementBase { virtual void foo() { } /* Force creation of virtual table */ };
+struct ElementA : ElementBase {
+    ElementA(int v) : v(v) { }
+    int value() { return v; }
+    int v;
+};
+
+struct ElementList {
+    void add(std::shared_ptr<ElementBase> e) { l.push_back(e); }
+    std::vector<std::shared_ptr<ElementBase>> l;
+};
+
 test_initializer smart_ptr_and_references([](py::module &pm) {
     auto m = pm.def_submodule("smart_ptr");
 
@@ -309,4 +321,21 @@
     py::class_<HeldByDefaultHolder>(m, "HeldByDefaultHolder")
         .def(py::init<>())
         .def_static("load_shared_ptr", [](std::shared_ptr<HeldByDefaultHolder>) {});
+
+    // #187: issue involving std::shared_ptr<> return value policy & garbage collection
+    py::class_<ElementBase, std::shared_ptr<ElementBase>>(m, "ElementBase");
+
+    py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(m, "ElementA")
+        .def(py::init<int>())
+        .def("value", &ElementA::value);
+
+    py::class_<ElementList, std::shared_ptr<ElementList>>(m, "ElementList")
+        .def(py::init<>())
+        .def("add", &ElementList::add)
+        .def("get", [](ElementList &el) {
+            py::list list;
+            for (auto &e : el.l)
+                list.append(py::cast(e));
+            return list;
+        });
 });
diff --git a/tests/test_smart_ptr.py b/tests/test_smart_ptr.py
index 7396c9f..144180d 100644
--- a/tests/test_smart_ptr.py
+++ b/tests/test_smart_ptr.py
@@ -234,3 +234,15 @@
     with pytest.raises(RuntimeError) as excinfo:
         HeldByDefaultHolder.load_shared_ptr(instance)
     assert "Unable to load a custom holder type from a default-holder instance" in str(excinfo)
+
+
+def test_shared_ptr_gc():
+    """#187: issue involving std::shared_ptr<> return value policy & garbage collection"""
+    from pybind11_tests.smart_ptr import ElementList, ElementA
+
+    el = ElementList()
+    for i in range(10):
+        el.add(ElementA(i))
+    pytest.gc_collect()
+    for i, v in enumerate(el.get()):
+        assert i == v.value()
diff --git a/tests/test_virtual_functions.cpp b/tests/test_virtual_functions.cpp
index 5080b6d..b42f650 100644
--- a/tests/test_virtual_functions.cpp
+++ b/tests/test_virtual_functions.cpp
@@ -311,6 +311,16 @@
 
 };
 
+struct Base {
+    /* for some reason MSVC2015 can't compile this if the function is pure virtual */
+    virtual std::string dispatch() const { return {}; };
+};
+
+struct DispatchIssue : Base {
+    virtual std::string dispatch() const {
+        PYBIND11_OVERLOAD_PURE(std::string, Base, dispatch, /* no arguments */);
+    }
+};
 
 test_initializer virtual_functions([](py::module &m) {
     py::class_<ExampleVirt, PyExampleVirt>(m, "ExampleVirt")
@@ -341,4 +351,51 @@
 
     m.def("cstats_debug", &ConstructorStats::get<ExampleVirt>);
     initialize_inherited_virtuals(m);
+
+    // #159: virtual function dispatch has problems with similar-named functions
+    py::class_<Base, DispatchIssue>(m, "DispatchIssue")
+        .def(py::init<>())
+        .def("dispatch", &Base::dispatch);
+
+    m.def("dispatch_issue_go", [](const Base * b) { return b->dispatch(); });
+
+    // #392/397: overridding reference-returning functions
+    class OverrideTest {
+    public:
+        struct A { std::string value = "hi"; };
+        std::string v;
+        A a;
+        explicit OverrideTest(const std::string &v) : v{v} {}
+        virtual std::string str_value() { return v; }
+        virtual std::string &str_ref() { return v; }
+        virtual A A_value() { return a; }
+        virtual A &A_ref() { return a; }
+    };
+
+    class PyOverrideTest : public OverrideTest {
+    public:
+        using OverrideTest::OverrideTest;
+        std::string str_value() override { PYBIND11_OVERLOAD(std::string, OverrideTest, str_value); }
+        // Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
+        // to a python numeric value, since we only copy values in the numeric type caster:
+//      std::string &str_ref() override { PYBIND11_OVERLOAD(std::string &, OverrideTest, str_ref); }
+        // But we can work around it like this:
+    private:
+        std::string _tmp;
+        std::string str_ref_helper() { PYBIND11_OVERLOAD(std::string, OverrideTest, str_ref); }
+    public:
+        std::string &str_ref() override { return _tmp = str_ref_helper(); }
+
+        A A_value() override { PYBIND11_OVERLOAD(A, OverrideTest, A_value); }
+        A &A_ref() override { PYBIND11_OVERLOAD(A &, OverrideTest, A_ref); }
+    };
+
+    py::class_<OverrideTest::A>(m, "OverrideTest_A")
+        .def_readwrite("value", &OverrideTest::A::value);
+    py::class_<OverrideTest, PyOverrideTest>(m, "OverrideTest")
+        .def(py::init<const std::string &>())
+        .def("str_value", &OverrideTest::str_value)
+//      .def("str_ref", &OverrideTest::str_ref)
+        .def("A_value", &OverrideTest::A_value)
+        .def("A_ref", &OverrideTest::A_ref);
 });
diff --git a/tests/test_virtual_functions.py b/tests/test_virtual_functions.py
index b11c699..3ec6fc2 100644
--- a/tests/test_virtual_functions.py
+++ b/tests/test_virtual_functions.py
@@ -257,3 +257,42 @@
     assert mv_stats.copy_constructions == 1
     assert nc_stats.move_constructions >= 0
     assert mv_stats.move_constructions >= 0
+
+
+def test_dispatch_issue(msg):
+    """#159: virtual function dispatch has problems with similar-named functions"""
+    from pybind11_tests import DispatchIssue, dispatch_issue_go
+
+    class PyClass1(DispatchIssue):
+        def dispatch(self):
+            return "Yay.."
+
+    class PyClass2(DispatchIssue):
+        def dispatch(self):
+            with pytest.raises(RuntimeError) as excinfo:
+                super(PyClass2, self).dispatch()
+            assert msg(excinfo.value) == 'Tried to call pure virtual function "Base::dispatch"'
+
+            p = PyClass1()
+            return dispatch_issue_go(p)
+
+    b = PyClass2()
+    assert dispatch_issue_go(b) == "Yay.."
+
+
+def test_override_ref():
+    """#392/397: overridding reference-returning functions"""
+    from pybind11_tests import OverrideTest
+
+    o = OverrideTest("asdf")
+
+    # Not allowed (see associated .cpp comment)
+    # i = o.str_ref()
+    # assert o.str_ref() == "asdf"
+    assert o.str_value() == "asdf"
+
+    assert o.A_value().value == "hi"
+    a = o.A_ref()
+    assert a.value == "hi"
+    a.value = "bye"
+    assert a.value == "bye"