void jump(QString _method) {

}

namespace pybind11 { namespace detail {
    template <> struct type_caster<QVariant> {
    public:
        /**
         * This macro establishes the name 'bool' in
         * function signatures and declares a local variable
         * 'value' of type QVariant
         */
        PYBIND11_TYPE_CASTER(QVariant, _("bool"));

        /**
         * Conversion part 1 (Python->C++): convert a PyObject into a inty
         * instance or return false upon failure. The second argument
         * indicates whether implicit conversions should be applied.
         */
        bool load(handle src, bool ) {
            /* Extract PyObject from handle */
            PyObject *source = src.ptr();

            /* Safety check, if we have a bool here */
            if (!PyBool_Check(source))
                return false;

            /* Now try to convert into a C++ int */
            value = QVariant::fromValue(source == Py_True);

            /* Ensure return code was OK (to avoid out-of-range errors etc) */
            return ( !PyErr_Occurred() );
        }

        /**
         * Conversion part 2 (C++ -> Python): convert an QVariant instance into
         * a Python object. The second and third arguments are used to
         * indicate the return value policy and parent object (for
         * ``return_value_policy::reference_internal``) and are generally
         * ignored by implicit casters.
         */
        static handle cast(QVariant src, return_value_policy /* policy */, handle /* parent */) {
            return (PyBool_FromLong(src.toBool()) );
        }
    };
}} // namespace pybind11::detail

 const QMetaObject* meta = core_->metaObject();

     //std::cerr << "Number of methods:" << meta->methodCount() << std::end;

     for ( int i = 0 ; i < meta->methodCount() ; ++i) {

       QMetaMethod method = meta->method(i);
       if ( method.access() == QMetaMethod::Public && method.methodType() == QMetaMethod::Slot) {

         QString functionName = QString::fromLatin1(method.methodSignature());

         functionName.truncate(functionName.indexOf("("));

         // First try to
         if (method.parameterCount() == 0) {
           std::cerr <<  QString::fromLatin1(method.methodSignature()).toStdString() << std::endl;

           QString function = QString::fromLatin1(method.methodSignature()).remove(QRegExp("[()]"));

           QByteArray ba = function.toLocal8Bit();

           std::cerr << "Registering " << ba.data() << "  with return type : " << method.returnType() << " which is " << method.typeName() <<  std::endl;

           // We are only registering functions with no return type for now!
           if ( QString(method.typeName()) == "void") {
             core.def(ba.data(),  [ method ](const Core& a) {
                                                               std::cerr << "Calling " << QString::fromLatin1(method.methodSignature()).toStdString() << std::endl;
                                                               method.invoke( core_ ,  Qt::DirectConnection);
                                                            });
           } else {
             core.def(ba.data(),  [ method ](const Core& a) { std::cerr << "No implementation for calling : " << QString::fromLatin1(method.methodSignature()).toStdString() << " due to return type" << std::endl; });
           }

         }

         if (method.parameterCount() == 1) {
           std::cerr <<  QString::fromLatin1(method.methodSignature()).toStdString() << std::endl;

           QByteArray ba = functionName.toLocal8Bit();

           std::cerr << "Registering " << ba.data() << "  with return type : " << method.returnType() << " which is " << method.typeName() <<  std::endl;

           std::cerr << "Parameters: " << QString::fromLatin1(method.parameterNames()[0]).toStdString() << QMetaType::typeName(method.parameterType(0)) <<std::endl;


           QString description;
           QStringList parameters;
           QStringList descriptions;

           core_->slotGetDescription("core."+QString::fromLatin1(method.methodSignature()),   description, parameters, descriptions );

           std::cerr << "Description: " << description.toStdString() << std::endl;

           if ( QString(QMetaType::typeName(method.parameterType(0))) == "bool" || QString(QMetaType::typeName(method.parameterType(0))) == "int") {
             core.def(ba.data(),  [ method ](const Core& a, QVariant _arg) {
                                                              std::cerr << "Calling " << QString::fromLatin1(method.methodSignature()).toStdString() << std::endl;
                                                              method.invoke( core_ ,  Qt::DirectConnection,   Q_ARG(bool, _arg.toBool()) );
                                                             }, py::arg(method.parameterNames()[0].data() ) );

           } else {
              std::cerr << "Unable to register on parameter function " << std::endl;

           }
         }

       }
     }
     
// Remove this!
//  core.def("__del__",
//      []() {
//    std::cerr << "deleting Core" << std::endl;
//  });
     

PYBIND11_EMBEDDED_MODULE(examples, m) {
    m.doc() = "pybind11 example plugin"; // optional module docstring
    m.def("add", &add, "A function which adds two numbers");
}




int add(int i, int j) {
    return i + j;
}
