private void onMessage(String msg) {
        // TODO call the callback obj in case of callback. If not send call the
        // method!
        JSONObject json = JSONObject.fromObject(msg);
        if (!json.has("callback")) {
            System.err.println("No callback: " + msg);
            return;
        }
        boolean callback = json.optBoolean("callback");
        final String reqId = json.optString("reqId", null);
        final JSONObject data = json.optJSONObject("data");
        if (data == null) {
            System.err.println("No data object in : " + msg);
            return;
        }
        if (callback) {
            final Callback cb;
            synchronized (calls) {
                cb = calls.get(reqId);
            }
            if (reqId != null && cb != null) {
                final String err;
                if (data.optJSONObject("err") == null) {
                    err = null;
                } else {
                    err = data.optString("err", null);
                }
                final JSONObject d = data.optJSONObject("data");
                if (cb != Callback.EMPTY) {
                    Thread newThread = new Thread() {
                        @Override
                        public void run() {
                            cb.callback(err, d);
                        }
                    };
                    newThread.start();
                }
                synchronized (calls) {
                    calls.remove(reqId);
                }
            } else {
                System.err.println("There is no callback for reqId: " + reqId);
            }
        } else {
            Thread newProcess = new Thread() {
                @Override
                public void run() {
                    main.onMessage(data, new Callback() {
                        public void callback(String err, JSONObject data) {
                            JSONObject m = new JSONObject();
                            JSONObject d = new JSONObject();

                            d.element("err", (err == null ? JSONNull.getInstance() : err));
                            d.element("data", data);
                            m.element("callback", true);
                            m.element("reqId", reqId);
                            m.element("data", d);
                            placeInOut(m);

                            // Callback is the point of exit. Therefore we can
                            // assume at this point thread execution is over
                            throttler.onThreadExit();
                        }
                    });
                }
            };
            throttler.push(newProcess);
        }
    }