void paramCb(const TokenPtr& msg)
 {
     if (std::dynamic_pointer_cast<EndOfSequenceMessage const>(msg->getTokenData())) {
         return;
     }
     params_.push_back(msg->getTokenData());
 }
    void fitnessCb(const TokenPtr& data)
    {
        if (auto val = std::dynamic_pointer_cast<GenericValueMessage<double> const>(data->getTokenData())) {
            //            std::unique_lock<std::mutex> lock(data_available_mutex_);
            fitness_.push_back(val->value);

        } else if (std::dynamic_pointer_cast<EndOfSequenceMessage const>(data->getTokenData())) {
        } else {
            throw std::runtime_error("unkown message recieved: " + data->getTokenData()->typeName());
        }
    }
TEST_F(AutoGenerateTest, ExplicitTypesAreDetected)
{
    factory.registerNodeType(GenericNodeFactory::createConstructorFromFunction(f1, "f1"));

    UUID node_id = UUIDProvider::makeUUID_without_parent("foobarbaz");
    NodeFacadeImplementationPtr node = factory.makeNode("f1", node_id, uuid_provider);

    ASSERT_TRUE(node != nullptr);
    ASSERT_EQ(node_id, node->getUUID());

    ASSERT_EQ(node->getParameters().size(), 1);

    ASSERT_EQ(node->getInputs().size(), 2 + node->getParameters().size());
    ASSERT_EQ(node->getOutputs().size(), 1 + node->getParameters().size());

    GenericValueMessage<int>::Ptr a(new GenericValueMessage<int>);
    GenericValueMessage<int>::Ptr b(new GenericValueMessage<int>);

    a->value = 23;
    b->value = 42;

    InputPtr i1 = node->getNodeHandle()->getInput(UUIDProvider::makeDerivedUUID_forced(node_id, "in_0"));
    ASSERT_TRUE(i1 != nullptr);

    InputPtr i2 = node->getNodeHandle()->getInput(UUIDProvider::makeDerivedUUID_forced(node_id, "in_1"));
    ASSERT_TRUE(i2 != nullptr);

    TokenPtr ta = std::make_shared<Token>(a);
    TokenPtr tb = std::make_shared<Token>(b);

    param::ParameterPtr p = node->getParameter("param 2");
    ASSERT_TRUE(p != nullptr);

    p->set<int>(1337);

    param::ValueParameter::Ptr vp = std::dynamic_pointer_cast<param::ValueParameter>(p);
    ASSERT_TRUE(vp != nullptr);

    i1->setToken(ta);
    i2->setToken(tb);

    NodePtr n = node->getNode();
    n->process(*node->getNodeHandle(), *n);

    OutputPtr o = node->getNodeHandle()->getOutput(UUIDProvider::makeDerivedUUID_forced(node_id, "out_0"));
    ASSERT_TRUE(o != nullptr);

    o->commitMessages(false);

    TokenPtr to = o->getToken();
    ASSERT_TRUE(to != nullptr);
    ASSERT_TRUE(to->getTokenData() != nullptr);

    GenericValueMessage<int>::ConstPtr result = std::dynamic_pointer_cast<GenericValueMessage<int> const>(to->getTokenData());
    ASSERT_TRUE(result != nullptr);

    ASSERT_EQ((a->value + b->value + vp->as<int>()), result->value);
}
UUID SubgraphNode::addForwardingOutput(const UUID& internal_uuid, const TokenDataConstPtr& type, const std::string& label)
{
    graph_->registerUUID(internal_uuid);

    Output* external_output = VariadicOutputs::createVariadicOutput(type, label);

    InputPtr relay = createInternalInput(type, internal_uuid, label, true);

    crossConnectLabelChange(external_output, relay.get());

    std::weak_ptr<Output> external_output_weak = std::dynamic_pointer_cast<Output>(external_output->shared_from_this());
    relay->message_set.connect([this, external_output_weak, relay](Connectable*) {
        if (auto external_output = external_output_weak.lock()) {
            TokenPtr token = relay->getToken();
            if (is_iterating_) {
                connection_types::GenericVectorMessage::Ptr vector;
                if (!external_output->hasMessage()) {
                    vector = connection_types::GenericVectorMessage::make(token->getTokenData());
                } else {
                    auto collected = external_output->getAddedToken()->getTokenData()->cloneAs<TokenData>();
                    vector = std::dynamic_pointer_cast<connection_types::GenericVectorMessage>(collected);
                }
                apex_assert(vector);
                vector->addNestedValue(token->getTokenData());
                msg::publish(external_output.get(), vector);

                external_output->setType(vector);

            } else {
                msg::publish(external_output.get(), token->getTokenData());
            }
        }
    });

    external_to_internal_inputs_[external_output->getUUID()] = relay;

    relay_to_external_output_[internal_uuid] = external_output->getUUID();

    forwarding_connector_added(relay);

    return external_output->getUUID();
}
TEST_F(AutoGenerateTest, OrderDoesNotMatterTypesAreDetected)
{
    factory.registerNodeType(GenericNodeFactory::createConstructorFromFunction(f3, "f3"));

    UUID node_id = UUIDProvider::makeUUID_without_parent("foobarbaz");
    NodeFacadeImplementationPtr node = factory.makeNode("f3", node_id, uuid_provider);

    ASSERT_TRUE(node != nullptr);
    ASSERT_EQ(node_id, node->getUUID());

    ASSERT_EQ(node->getParameters().size(), 3);

    ASSERT_EQ(node->getInputs().size(), 2 + node->getParameters().size());
    ASSERT_EQ(node->getOutputs().size(), 1 + node->getParameters().size());

    GenericValueMessage<int>::Ptr a(new GenericValueMessage<int>);
    GenericValueMessage<double>::Ptr b(new GenericValueMessage<double>);

    a->value = 23;
    b->value = 42.0;

    InputPtr i1 = node->getNodeHandle()->getInput(UUIDProvider::makeDerivedUUID_forced(node_id, "in_0"));
    ASSERT_TRUE(i1 != nullptr);

    InputPtr i2 = node->getNodeHandle()->getInput(UUIDProvider::makeDerivedUUID_forced(node_id, "in_1"));
    ASSERT_TRUE(i2 != nullptr);

    TokenPtr ta = std::make_shared<Token>(a);
    TokenPtr tb = std::make_shared<Token>(b);

    param::ParameterPtr p_1 = node->getParameter("param 0");
    ASSERT_TRUE(p_1 != nullptr);
    p_1->set<int>(1337);

    param::ParameterPtr p_2 = node->getParameter("param 4");
    ASSERT_TRUE(p_2 != nullptr);
    p_2->set<int>(4);

    param::ParameterPtr p_3 = node->getParameter("param 5");
    ASSERT_TRUE(p_3 != nullptr);
    p_3->set<int>(5);

    i1->setToken(ta);
    i2->setToken(tb);

    NodePtr n = node->getNode();
    n->process(*node->getNodeHandle(), *n);

    OutputPtr o = node->getNodeHandle()->getOutput(UUIDProvider::makeDerivedUUID_forced(node_id, "out_0"));
    ASSERT_TRUE(o != nullptr);

    o->commitMessages(false);

    TokenPtr to = o->getToken();
    ASSERT_TRUE(to != nullptr);
    ASSERT_TRUE(to->getTokenData() != nullptr);

    GenericValueMessage<std::string>::ConstPtr result = std::dynamic_pointer_cast<GenericValueMessage<std::string> const>(to->getTokenData());
    ASSERT_TRUE(result != nullptr);

    ASSERT_EQ("1411", result->value);
}