support for opaque types
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f8a489c..900e26e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -119,6 +119,7 @@
   example/example11.cpp
   example/example12.cpp
   example/example13.cpp
+  example/example14.cpp
   example/issues.cpp
 )
 
diff --git a/docs/advanced.rst b/docs/advanced.rst
index f24d3b5..74611bd 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -1021,7 +1021,7 @@
 
 It's straightforward to split binding code over multiple extension modules, while
 referencing types that are declared elsewhere. Everything "just" works without any special
-precautions. One exception to this rule occurs when wanting to extend a type declared
+precautions. One exception to this rule occurs when extending a type declared
 in another extension module. Recall the basic example from Section
 :ref:`inheritance`.
 
@@ -1063,3 +1063,55 @@
     py::class_<Dog>(m, "Dog", py::base<Pet>())
         .def(py::init<const std::string &>())
         .def("bark", &Dog::bark);
+
+Treating STL data structures as opaque objects
+==============================================
+
+pybind11 heavily relies on a template matching mechanism to convert parameters
+and return values that are constructed from STL data types such as vectors,
+linked lists, hash tables, etc. This even works in a recursive manner, for
+instance to deal with lists of hash maps of pairs of elementary and custom
+types, etc.
+
+The fundamental limitation of this approach is the internal conversion between
+Python and C++ types involves a copy operation that prevents pass-by-reference
+semantics. What does this mean?
+
+Suppose we bind the following function
+
+.. code-block:: cpp
+
+    void append_1(std::vector<int> &v) {
+       v.push_back(1);
+    }
+
+and call it as follows from Python:
+
+.. code-block:: python
+
+   >>> v = [5, 6]
+   >>> append_1(v)
+   >>> print(v)
+   [5, 6]
+
+As you can see, when passing STL data structures by reference, modifications
+are not propagated back the Python side. To deal with situations where this
+desirable, pybind11 contains a simple template wrapper class named ``opaque<T>``.
+
+``opaque<T>`` disables the underlying template machinery for
+``T`` and can be used to treat STL types as opaque objects, whose contents are
+never inspected or extracted (thus, they can be passed by reference).
+The downside of this approach is that it the binding code becomes a bit more
+wordy. The above function can be bound using the following wrapper code:
+
+.. code-block:: cpp
+
+   m.def("append_1", [](py::opaque<std::vector<int>> &v) { append_1(v); });
+
+Opaque types must also have a dedicated ``class_`` declaration to define a
+set of admissible operations.
+
+.. seealso::
+
+    The file :file:`example/example14.cpp` contains a complete example that
+    demonstrates how to create opaque types using pybind11 in more detail.
diff --git a/example/example.cpp b/example/example.cpp
index d84b456..a4fb4d3 100644
--- a/example/example.cpp
+++ b/example/example.cpp
@@ -22,6 +22,7 @@
 void init_ex11(py::module &);
 void init_ex12(py::module &);
 void init_ex13(py::module &);
+void init_ex14(py::module &);
 void init_issues(py::module &);
 
 PYBIND11_PLUGIN(example) {
@@ -40,6 +41,7 @@
     init_ex11(m);
     init_ex12(m);
     init_ex13(m);
+    init_ex14(m);
     init_issues(m);
 
     return m.ptr();
diff --git a/example/example14.cpp b/example/example14.cpp
new file mode 100644
index 0000000..5c6d918
--- /dev/null
+++ b/example/example14.cpp
@@ -0,0 +1,29 @@
+/*
+    example/example14.cpp -- opaque types
+
+    Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.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 "example.h"
+#include <pybind11/stl.h>
+#include <vector>
+
+typedef std::vector<std::string> StringList;
+
+void init_ex14(py::module &m) {
+    py::class_<py::opaque<StringList>>(m, "StringList")
+        .def(py::init<>())
+        .def("push_back", [](py::opaque<StringList> &l, const std::string &str) { l->push_back(str); })
+        .def("pop_back", [](py::opaque<StringList> &l) { l->pop_back(); })
+        .def("back", [](py::opaque<StringList> &l) { return l->back(); });
+
+    m.def("print_opaque_list", [](py::opaque<StringList> &_l) {
+        StringList &l = _l;
+        std::cout << "Opaque list: " << std::endl;
+        for (auto entry : l)
+           std::cout << "  " << entry << std::endl; 
+    });
+}
diff --git a/example/example14.py b/example/example14.py
new file mode 100644
index 0000000..c9c8665
--- /dev/null
+++ b/example/example14.py
@@ -0,0 +1,14 @@
+from __future__ import print_function
+import sys
+
+sys.path.append('.')
+
+from example import StringList, print_opaque_list
+
+l = StringList()
+l.push_back("Element 1")
+l.push_back("Element 2")
+print_opaque_list(l)
+print("Back element is %s" % l.back())
+l.pop_back()
+print_opaque_list(l)
diff --git a/example/example14.ref b/example/example14.ref
new file mode 100644
index 0000000..d738fef
--- /dev/null
+++ b/example/example14.ref
@@ -0,0 +1,6 @@
+Opaque list: 
+  Element 1
+  Element 2
+Back element is Element 2
+Opaque list: 
+  Element 1
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 89fcac1..f36b3d5 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -17,6 +17,21 @@
 #include <limits>
 
 NAMESPACE_BEGIN(pybind11)
+
+/// Thin wrapper type used to treat certain data types as opaque (e.g. STL vectors, etc.)
+template <typename Type> class opaque {
+public:
+    template <typename... Args> opaque(Args&&... args) : value(std::forward<Args>(args)...) { }
+    operator Type&() { return value; }
+    operator const Type&() const { return value; }
+    operator Type*() { return &value; }
+    operator const Type*() const { return &value; }
+    Type* operator->() { return &value; }
+    const Type* operator->() const { return &value; }
+private:
+    Type value;
+};
+
 NAMESPACE_BEGIN(detail)
 
 /// Additional type information which does not fit into the PyTypeObject