bool TrainModule::respond(const yarp::os::Bottle& cmd, yarp::os::Bottle& reply) {
    // NOTE: the module class spawns a new thread, which implies that exception
    // handling needs to be done in this thread, so not the 'main' thread.
    bool success = false;

    try {
        switch(cmd.get(0).asVocab()) {
            case VOCAB4('h','e','l','p'): // print help information
                reply.add(yarp::os::Value::makeVocab("help"));

                reply.addString("Training module configuration options");
                reply.addString("  help                  Displays this message");
                reply.addString("  train                 Trains the machine and sends the model");
                reply.addString("  model                 Sends the model to the prediction module");
                reply.addString("  reset                 Resets the machine to its current state");
                reply.addString("  info                  Outputs information about the machine");
                reply.addString("  pause                 Disable passing the samples to the machine");
                reply.addString("  continue              Enable passing the samples to the machine");
                reply.addString("  set key val           Sets a configuration option for the machine");
                reply.addString("  load fname            Loads a machine from a file");
                reply.addString("  save fname            Saves the current machine to a file");
                reply.addString("  event [cmd ...]       Sends commands to event dispatcher (see: event help)");
                reply.addString("  cmd fname             Loads commands from a file");
                reply.addString(this->getMachine().getConfigHelp().c_str());
                success = true;
                break;

            case VOCAB4('t','r','a','i'): // train the machine, implies sending model
                this->getMachine().train();
                reply.addString("Training completed.");

            case VOCAB4('m','o','d','e'): // send model
                this->model_out.write(this->machinePortable);
                reply.addString("The model has been written to the port.");
                success = true;
                break;

            case VOCAB4('c','l','e','a'): // clear machine
            case VOCAB3('c','l','r'):
            case VOCAB4('r','e','s','e'): // reset
            case VOCAB3('r','s','t'):
                this->getMachine().reset();
                reply.addString("Machine cleared.");
                success = true;
                break;

            case VOCAB4('p','a','u','s'): // pause sample stream
            case VOCAB4('d','i','s','a'): // disable
                this->trainProcessor.setEnabled(false);
                reply.addString("Sample stream to machine disabled.");
                success = true;
                break;

            case VOCAB4('c','o','n','t'): // continue sample stream
            case VOCAB4('e','n','a','b'): // enable
                this->trainProcessor.setEnabled(true);
                reply.addString("Sample stream to machine enabled.");
                success = true;
                break;

            case VOCAB4('i','n','f','o'): // information
            case VOCAB4('s','t','a','t'): // statistics
                { // prevent identifier initialization to cross borders of case
                reply.add(yarp::os::Value::makeVocab("help"));
                reply.addString("Machine Information: ");
                reply.addString(this->getMachine().getInfo().c_str());
                success = true;
                break;
                }

            case VOCAB4('l','o','a','d'): // load
                { // prevent identifier initialization to cross borders of case
                reply.add(yarp::os::Value::makeVocab("help"));
                std::string replymsg = std::string("Loading machine from '") +
                                       cmd.get(1).asString().c_str() + "'... " ;
                if(!cmd.get(1).isString()) {
                    replymsg += "failed";
                } else {
                    this->getMachinePortable().readFromFile(cmd.get(1).asString().c_str());
                    replymsg += "succeeded";
                }
                reply.addString(replymsg.c_str());
                success = true;
                break;
                }

            case VOCAB4('s','a','v','e'): // save
                { // prevent identifier initialization to cross borders of case
                reply.add(yarp::os::Value::makeVocab("help"));
                std::string replymsg = std::string("Saving machine to '") +
                                       cmd.get(1).asString().c_str() + "'... " ;
                if(!cmd.get(1).isString()) {
                    replymsg += "failed";
                } else {
                    this->getMachinePortable().writeToFile(cmd.get(1).asString().c_str());
                    replymsg += "succeeded";
                }
                reply.addString(replymsg.c_str());
                success = true;
                break;
                }

            case VOCAB3('s','e','t'): // set a configuration option for the machine
                { // prevent identifier initialization to cross borders of case
                yarp::os::Bottle property;
                /*
                 * This is a simple hack to enable multiple parameters The need
                 * for this hack lies in the fact that a group can only be found
                 * using findGroup if it is a nested list in a Bottle. If the
                 * Bottle itself is the list, then the group will _not_ be found.
                 */
                property.addList() = cmd.tail();
                std::string replymsg = "Setting configuration option ";
                bool ok = this->getMachine().configure(property);
                replymsg += ok ? "succeeded" :
                                 "failed; please check key and value type.";
                reply.addString(replymsg.c_str());
                success = true;
                break;
                }

            case VOCAB4('e','v','e','n'): // event
                { // prevent identifier initialization to cross borders of case
                success = this->dmanager.respond(cmd.tail(), reply);
                break;
                }

            case VOCAB3('c','m','d'): // cmd
            case VOCAB4('c','o','m','m'): // command
                { // prevent identifier initialization to cross borders of case
                reply.add(yarp::os::Value::makeVocab("help"));
                std::string replymsg;
                if(!cmd.get(1).isString()) {
                    replymsg = "Please supply a valid filename.";
                } else {
                    std::string full_fname = this->findFile(cmd.get(1).asString().c_str());
                    replymsg = std::string("Loading commands from '") +
                                           full_fname + "'... " ;
                    this->loadCommandFile(full_fname, &reply);
                    replymsg += "succeeded";
                }
                reply.addString(replymsg.c_str());
                success = true;
                break;
                }

            default:
                break;

        }
    } catch(const std::exception& e) {
        std::string msg = std::string("Error: ") + e.what();
        reply.addString(msg.c_str());
        success = true;
    }

    return success;
}
bool DispatcherManager::respond(const yarp::os::Bottle& cmd, yarp::os::Bottle& reply) {
    bool success = false;

    try {
        switch(cmd.get(0).asVocab()) {
            case VOCAB4('h','e','l','p'): // print help information
                reply.add(yarp::os::Value::makeVocab("help"));

                reply.addString("Event Manager configuration options");
                reply.addString("  help                  Displays this message");
                reply.addString("  list                  Print a list of available event listeners");
                reply.addString("  add type [type2 ...]  Adds one or more event listeners");
                reply.addString("  remove [all|idx]      Removes event listener at an index or all");
                reply.addString("  set [all|idx]         Configures a listener");
                reply.addString("  stats                 Prints information");
                success = true;
                break;

            case VOCAB4('l','i','s','t'): // print list of available event listeners
                {
                reply.add(yarp::os::Value::makeVocab("help"));
                std::vector<std::string> keys = FactoryT<std::string, IEventListener>::instance().getKeys();
                for(unsigned int i = 0; i < keys.size(); i++) {
                    reply.addString((std::string("  ") + keys[i]).c_str());
                }
                success = true;
                break;
                }

            case VOCAB3('a','d','d'): // add
                { // prevent identifier initialization to cross borders of case
                yarp::os::Bottle list = cmd.tail();
                for(int i = 0; i < list.size(); i++) {
                    IEventListener* listener = this->factory->create(list.get(i).asString().c_str());
                    listener->start();
                    this->dispatcher->addListener(listener);
                }
                reply.addString("Successfully added listener(s)");
                success = true;
                break;
                }

            case VOCAB4('r','e','m','o'): // remove
            case VOCAB3('d','e','l'): // del(ete)
                { // prevent identifier initialization to cross borders of case
                if(cmd.get(1).isInt() && cmd.get(1).asInt() >= 1 && cmd.get(1).asInt() <= this->dispatcher->countListeners()) {
                    this->dispatcher->removeListener(cmd.get(1).asInt()-1);
                    reply.addString("Successfully removed listener.");
                    success = true;
                } else if(cmd.get(1).asString() == "all") {
                    this->dispatcher->clear();
                    reply.addString("Successfully removed all listeners.");
                    success = true;
                } else {
                    throw std::runtime_error("Illegal index!");
                }
                break;
                }

            case VOCAB3('s','e','t'): // set
                { // prevent identifier initialization to cross borders of case
                yarp::os::Bottle property;
                property.addList() = cmd.tail().tail(); // see comment in TrainModule

                std::string replymsg = "Setting configuration option ";
                if(cmd.get(1).isInt() && cmd.get(1).asInt() >= 1 &&
                   cmd.get(1).asInt() <= this->dispatcher->countListeners()) {

                    bool ok = this->dispatcher->getAt(cmd.get(1).asInt()-1).configure(property);
                    replymsg += ok ? "succeeded" :
                                     "failed; please check key and value type.";
                    reply.addString(replymsg.c_str());
                    success = true;
                } else if(cmd.get(1).asString() == "all") {
                    for(int i = 0; i < this->dispatcher->countListeners(); i++) {
                        if(i > 0) {
                            replymsg += ", ";
                        }
                        bool ok = this->dispatcher->getAt(i).configure(property);
                        replymsg += ok ? "succeeded" :
                                        "failed; please check key and value type.";
                    }
                    replymsg += ".";
                    reply.addString(replymsg.c_str());
                    success = true;
                } else {
                    throw std::runtime_error("Illegal index!");
                }
                break;
                }

            case VOCAB4('i','n','f','o'): // information
            case VOCAB4('s','t','a','t'): // statistics
                { // prevent identifier initialization to cross borders of case
                reply.add(yarp::os::Value::makeVocab("help"));
                std::ostringstream buffer;
                buffer << "Event Manager Information (" << this->dispatcher->countListeners() << " listeners)";
                reply.addString(buffer.str().c_str());
                for(int i = 0; i < this->dispatcher->countListeners(); i++) {
                    buffer.str(""); // why isn't there a proper reset method?
                    buffer << "  [" << (i + 1) << "] " << this->dispatcher->getAt(i).getInfo();
                    reply.addString(buffer.str().c_str());
                }

                success = true;
                break;
                }

            default:
                break;

        }
    } catch(const std::exception& e) {
        std::string msg = std::string("Error: ") + e.what();
        reply.addString(msg.c_str());
        success = true;
    }

    return success;
}
void SkeletonReader::run() {
	cout << " SkeletonReader" << endl;
	while (!stoploop) {
		//Checking if the bottle is good
		bot = in->read();
		if (bot != NULL) {
			if (bot->size() > 0) {
				SkeletonData* sd = new SkeletonData();
				//Creating a new ObjectData object and storing it in the DataCollector
				//Parses the Bottle created by the emulator
				if (emulator) {
					sd->setTimestamp(bot->get(0).asDouble());
					for (int i = 1; i < bot->size(); i++) {
						if (bot->get(i).asString() == "Head") {
							sd->setHeadX(bot->get(i + 2).asDouble());
							sd->setHeadY(bot->get(i + 3).asDouble());
							sd->setHeadZ(bot->get(i + 4).asDouble());
							if (i + 5 < bot->size()) {
								if (bot->get(i + 5).asString()
										== "Orientation") {
									double tmp[ARRAY_SIZE] = {
											bot->get(i + 7).asDouble(),
											bot->get(i + 8).asDouble(),
											bot->get(i + 9).asDouble(),
											bot->get(i + 10).asDouble(),
											bot->get(i + 11).asDouble(),
											bot->get(i + 12).asDouble(),
											bot->get(i + 13).asDouble(),
											bot->get(i + 14).asDouble(),
											bot->get(i + 15).asDouble() };
									vector<double> orientation;
									orientation.insert(orientation.begin(), tmp,
											tmp + ARRAY_SIZE);
									sd->setHeadOrientation(orientation);
								}
							}
						} else if (bot->get(i).asString() == "Left_Hand") {
							sd->setLeftHandX(bot->get(i + 2).asDouble());
							sd->setLeftHandY(bot->get(i + 3).asDouble());
							sd->setLeftHandZ(bot->get(i + 4).asDouble());
							if (i + 5 < bot->size()) {
								if (bot->get(i + 5).asString()
										== "Orientation") {
									double tmp[ARRAY_SIZE] = {
											bot->get(i + 7).asDouble(),
											bot->get(i + 8).asDouble(),
											bot->get(i + 9).asDouble(),
											bot->get(i + 10).asDouble(),
											bot->get(i + 11).asDouble(),
											bot->get(i + 12).asDouble(),
											bot->get(i + 13).asDouble(),
											bot->get(i + 14).asDouble(),
											bot->get(i + 15).asDouble() };
									vector<double> orientation;
									orientation.insert(orientation.begin(), tmp,
											tmp + ARRAY_SIZE);
									sd->setLeftHandOrientation(orientation);
								}
							}
						} else if (bot->get(i).asString() == "Right_Hand") {
							sd->setRightHandX(bot->get(i + 2).asDouble());
							sd->setRightHandY(bot->get(i + 3).asDouble());
							sd->setRightHandZ(bot->get(i + 4).asDouble());
							if (i + 5 < bot->size()) {
								if (bot->get(i + 5).asString()
										== "Orientation") {
									double tmp[ARRAY_SIZE] = {
											bot->get(i + 7).asDouble(),
											bot->get(i + 8).asDouble(),
											bot->get(i + 9).asDouble(),
											bot->get(i + 10).asDouble(),
											bot->get(i + 11).asDouble(),
											bot->get(i + 12).asDouble(),
											bot->get(i + 13).asDouble(),
											bot->get(i + 14).asDouble(),
											bot->get(i + 15).asDouble() };
									vector<double> orientation;
									orientation.insert(orientation.begin(), tmp,
											tmp + ARRAY_SIZE);
									sd->setRightHandOrientation(orientation);
								}
							}
						} else if (bot->get(i).asString() == "Chest") {
							sd->setChestX(bot->get(i + 2).asDouble());
							sd->setChestY(bot->get(i + 3).asDouble());
							sd->setChestZ(bot->get(i + 4).asDouble());
							if (i + 5 < bot->size()) {
								if (bot->get(i + 5).asString()
										== "Orientation") {
									double tmp[ARRAY_SIZE] = {
											bot->get(i + 7).asDouble(),
											bot->get(i + 8).asDouble(),
											bot->get(i + 9).asDouble(),
											bot->get(i + 10).asDouble(),
											bot->get(i + 11).asDouble(),
											bot->get(i + 12).asDouble(),
											bot->get(i + 13).asDouble(),
											bot->get(i + 14).asDouble(),
											bot->get(i + 15).asDouble() };
									vector<double> orientation;
									orientation.insert(orientation.begin(), tmp,
											tmp + ARRAY_SIZE);
									sd->setChestOrientation(orientation);
								}
							}
						}
					}
				} else {
					//Creating a new ObjectData object and storing it in the DataCollector
					//Parses the Bottle created by the KinectDeviceLocal of yarp
					in->getEnvelope(time);
					sd->setTimestamp(time.getTime());
					Bottle pos;
					int j = 0;
					for (int i = 0; i < bot->size(); i++) {
						switch (bot->get(i).asInt()) {
						case VOCAB3('P','O','S'):
							switch (j) {
							case HEAD_POS:
								sd->setHeadX(
										bot->get(i + 1).asList()->get(0).asDouble());
								sd->setHeadY(
										bot->get(i + 1).asList()->get(1).asDouble());
								sd->setHeadZ(
										bot->get(i + 1).asList()->get(2).asDouble());
								break;
							case CHEST_POS:
								sd->setChestX(
										bot->get(i + 1).asList()->get(0).asDouble());
								sd->setChestY(
										bot->get(i + 1).asList()->get(1).asDouble());
								sd->setChestZ(
										bot->get(i + 1).asList()->get(2).asDouble());
								break;
							case LEFT_HAND_POS:
								sd->setLeftHandX(
										bot->get(i + 1).asList()->get(0).asDouble());
								sd->setLeftHandY(
										bot->get(i + 1).asList()->get(1).asDouble());
								sd->setLeftHandZ(
										bot->get(i + 1).asList()->get(2).asDouble());
								break;
							case RIGHT_HAND_POS:
								sd->setRightHandX(
										bot->get(i + 1).asList()->get(0).asDouble());
								sd->setRightHandY(
										bot->get(i + 1).asList()->get(1).asDouble());
								sd->setRightHandZ(
										bot->get(i + 1).asList()->get(2).asDouble());
								break;
							}
							j++;
							break;
						}
					}
				}
				parent->addSkeletonData(sd);
			}
		}
	}
}