/** @file    <%- compInfo.name %>.cpp 
 *  @author  <%- compInfo.Authors %>
 *  @date    <%= (new Date()).toISOString() %>
 *  @brief   This file contains definitions for the <%- compInfo.name %> class; <%- compInfo['Brief Description'] %>
 */

#include "<%- compInfo.Package %>/<%- compInfo.name %>.hpp"

<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
// HFSM Includes
#include "<%- compInfo.Package %>/<%- compInfo.name %>_HFSM/<%- hfsm.sanitizedName %>_Events.hpp"
#include "<%- compInfo.Package %>/<%- compInfo.name %>_HFSM/<%- hfsm.sanitizedName %>_GeneratedStates.hpp"
<%
  });
}
-%>


// User Definitions
//::::<%- compInfo.path %>::::Definitions::::
<%- compInfo.Definitions %>

// Component Constructor
<%- compInfo.name %>::<%- compInfo.name %>(Json::Value& _config):
  Component::Component(_config)
{
}

// Component Initialization 
void <%- compInfo.name %>::init_timer_operation(const ros::TimerEvent& event)
{
  ros::Time __dequeue__ = ros::Time::now();
  // User Initialization Code
  try {
    {
      // print out the config that was passed in
      std::string configStr = config.toStyledString();
      std::cout << "Config: " << config << std::endl;
    }
<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
    {
      // now initialize the HFSM
      // update the "this_component" var for the HFSM
      <%- hfsm.sanitizedName %>_root->setComponentPtr( this );
      <%- hfsm.sanitizedName %>_root->initialize();
      // update the HFSM timer period and start the timer
      ros::Duration newPeriod = ros::Duration( <%- hfsm.sanitizedName %>_root->getActiveLeaf()->getTimerPeriod() );
      if (!<%- hfsm.sanitizedName %>_root->hasStopped()) {
        <%- hfsm.sanitizedName %>_HFSM_timer.setPeriod( newPeriod, false );
      } else {
        <%- hfsm.sanitizedName %>_HFSM_timer.stop();
      }
    }
<%
  });
}
-%>
    // now run the initialization code
    //::::<%- compInfo.path %>::::Initialization::::
    <%- compInfo.Initialization %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::initialization: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::initialization");
  }
  init_timer.stop();
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("init_timer_operation, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}

<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
// <%- hfsm.name %> Timer function
void <%- compInfo.name %>::<%- hfsm.sanitizedName %>_HFSM_timer_operation(const ros::TimerEvent& event)
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    StateMachine::Event* e = nullptr;
    // process all pending events
    while ( (e = eventFactory->getNextEvent()) != nullptr ) {
      <%- hfsm.sanitizedName %>_root->handleEvent( e );
      eventFactory->consumeEvent( e );
    }
    // run the HFSM tick event
    <%- hfsm.sanitizedName %>_root->tick();
    // process all events that may have been generated by the tick event
    while ( (e = eventFactory->getNextEvent()) != nullptr ) {
      <%- hfsm.sanitizedName %>_root->handleEvent( e );
      eventFactory->consumeEvent( e );
    }
    // update the timer period according to new active state
    ros::Duration newPeriod = ros::Duration( <%- hfsm.sanitizedName %>_root->getActiveLeaf()->getTimerPeriod() );
    if (!<%- hfsm.sanitizedName %>_root->hasStopped()) {
      <%- hfsm.sanitizedName %>_HFSM_timer.setPeriod( newPeriod, false );
    } else {
      <%- hfsm.sanitizedName %>_HFSM_timer.stop();
    }
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- hfsm.sanitizedName %>_HFSM_timer_operation: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- hfsm.sanitizedName %>_HFSM_timer_operation");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- hfsm.sanitizedName %>, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
<%
  });
}
-%>

<%
if (compInfo.Timer_list) {
  compInfo.Timer_list.map(function(tmr) {
-%>
// Timer Operation - <%- tmr.name %>
void <%- compInfo.name %>::<%- tmr.name %>_operation(const ros::TimerEvent& event)
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    //::::<%- tmr.path %>::::Operation::::
    <%- tmr.Operation %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- tmr.name %>_operation: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- tmr.name %>_operation");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- tmr.name %>, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
<%
  });
 }
-%>

<%
if (compInfo.Subscriber_list) {
  compInfo.Subscriber_list.map(function(sub) {
-%>
// Subscriber Operation - <%- sub.name %>
void <%- compInfo.name %>::<%- sub.name %>_operation(const ros::MessageEvent<<%- sub.Message.Package %>::<%- sub.Message.TypeName %> const>& event)
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    // get the publisher name, header, receipt time, and received_data from the event
    const std::string& publisher_node_name = event.getPublisherName();
    const boost::shared_ptr<ros::M_string>& headerPtr = event.getConnectionHeaderPtr();
    ros::Time receipt_time = event.getReceiptTime();
    const <%- sub.Message.Package %>::<%- sub.Message.TypeName %>::ConstPtr& received_data = event.getMessage();
    const <%- sub.Message.Package %>::<%- sub.Message.TypeName %>::ConstPtr& message = received_data;
    // now run the user's subscriber operation code
    //::::<%- sub.path %>::::Operation::::
    <%- sub.Operation %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- sub.name %>_operation: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- sub.name %>_operation");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- sub.name %>, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
<%
  });
 }
-%>

<%
if (compInfo.Server_list) {
  compInfo.Server_list.map(function(srv) {
-%>
// Server Operation - <%- srv.name %>
bool <%- compInfo.name %>::<%- srv.name %>_operation(const <%- srv.Service.Package %>::<%- srv.Service.TypeName %>::Request &req, <%- srv.Service.Package %>::<%- srv.Service.TypeName %>::Response &res )
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    // now run the user's server operation code
    //::::<%- srv.path %>::::Operation::::
    <%- srv.Operation %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- srv.name %>_operation: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- srv.name %>_operation");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- srv.name %>, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
  return true;
}
<%
  });
 }
-%>

<%
if (compInfo['Action Server_list']) {
  compInfo['Action Server_list'].map(function(srv) {
-%>
// Action Server Execute Callback - <%- srv.name %>
void <%- compInfo.name %>::<%- srv.name %>_execute_cb(const <%- srv.Action.Package %>::<%- srv.Action.TypeName %>GoalConstPtr &goal )
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    // now run the user's action server execute code
    //::::<%- srv.path %>::::Execute Callback::::
    <%- srv['Execute Callback'] %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- srv.name %>_execute_cb: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- srv.name %>_execute_cb");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- srv.name %>_execute, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
// Action Server Goal Callback - <%- srv.name %>
void <%- compInfo.name %>::<%- srv.name %>_goal_cb( )
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    // now run the user's action server goal recv code
    //::::<%- srv.path %>::::Goal Callback::::
    <%- srv['Goal Callback'] %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- srv.name %>_goal_cb: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- srv.name %>_goal_cb");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- srv.name %>_goal, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
// Action Server Preempt Callback - <%- srv.name %>
void <%- compInfo.name %>::<%- srv.name %>_preempt_cb( )
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    // now run the user's action server preempt code
    //::::<%- srv.path %>::::Preempt Callback::::
    <%- srv['Preempt Callback'] %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- srv.name %>_preempt_cb: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- srv.name %>_preempt_cb");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- srv.name %>_preempt, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
<%
  });
 }
-%>

<%
if (compInfo['Action Client_list']) {
  compInfo['Action Client_list'].map(function(clt) {
-%>
// Action Client Feedback Callback - <%- clt.name %>
void <%- compInfo.name %>::<%- clt.name %>_feedback_cb(const <%- clt.Action.Package %>::<%- clt.Action.TypeName %>FeedbackConstPtr &feedback)
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    // now run the user's action client feedback code
    //::::<%- clt.path %>::::Feedback Callback::::
    <%- clt['Feedback Callback'] %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- clt.name %>_feedback_cb: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- clt.name %>_feedback_cb");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- clt.name %>_feedback, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
// Action Client Active Callback - <%- clt.name %>
void <%- compInfo.name %>::<%- clt.name %>_active_cb( )
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    // now run the user's action client active code
    //::::<%- clt.path %>::::Active Callback::::
    <%- clt['Active Callback'] %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- clt.name %>_active_cb: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- clt.name %>_active_cb");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- clt.name %>_active, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
// Action Client Done Callback - <%- clt.name %>
void <%- compInfo.name %>::<%- clt.name %>_done_cb(const actionlib::SimpleClientGoalState& state, const <%- clt.Action.Package %>::<%- clt.Action.TypeName %>ResultConstPtr &result)
{
  ros::Time __dequeue__ = ros::Time::now();
  try {
    // now run the user's action client done code
    //::::<%- clt.path %>::::Done Callback::::
    <%- clt['Done Callback'] %>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::<%- clt.name %>_done_cb: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::<%- clt.name %>_done_cb");
  }
  ros::Time __completion__ = ros::Time::now();
  ros::Duration __execution__ = __completion__ - __dequeue__;
  trace->raw_log("<%- clt.name %>_done, %d.%09d, %d.%09d, %d.%09d, %d.%09d, %d.%09d",
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __dequeue__.sec,
		 __dequeue__.nsec,
		 __completion__.sec,
		 __completion__.nsec,
		 __execution__.sec,
		 __execution__.nsec,
		 0,
		 0);
}
<%
    });
 }
-%>

// Destructor - Cleanup Ports & Timers
<%- compInfo.name %>::~<%- compInfo.name %>()
{
  try {
    logger->log("DEBUG", "<%- compInfo.name %> calling user defined destruction");
    // User Destruction
    //::::<%- compInfo.path %>::::Destruction::::
    <%- compInfo.Destruction %>
<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
    <%- hfsm.sanitizedName %>_HFSM_timer.stop();
<%
  });
}
-%>
<%
if (compInfo.Timer_list) {
  compInfo.Timer_list.map(function(tmr) {
-%>
    <%- tmr.name %>.stop();
<%
	});
 }
-%>
<%
if (compInfo.Publisher_list) {
  compInfo.Publisher_list.map(function(pub) {
-%>
    <%- pub.name %>.shutdown();
<%
	});
 }
-%>
<%
if (compInfo.Subscriber_list) {
  compInfo.Subscriber_list.map(function(sub) {
-%>
    <%- sub.name %>.shutdown();
<%
	});
 }
-%>
<%
if (compInfo.Client_list) {
  compInfo.Client_list.map(function(clt) {
-%>
    <%- clt.name %>.shutdown();
<%
	});
 }
-%>
<%
if (compInfo.Server_list) {
  compInfo.Server_list.map(function(srv) {
-%>
    <%- srv.name %>.shutdown();
<%
	});
 }
-%>
<%
if (compInfo['Action Server_list']) {
  compInfo['Action Server_list'].map(function(srv) {
-%>
    <%- srv.name %>.shutdown();
<%
	});
 }
-%>
  } catch (std::exception& e) {
    // catch exceptions
    logger->log("ERROR", "std::exception caught in <%- compInfo.name %>::~<%- compInfo.name %>: %s", e.what());
  } catch ( ... ) {
    // catch everything else
    logger->log("ERROR", "unknown exception caught in <%- compInfo.name %>::~<%- compInfo.name %>");
  }
}

// Startup - Setup Component Ports & Timers
void <%- compInfo.name %>::startUp()
{
  std::string advertiseName;
  bool isOneShot;
  ros::TimerOptions timer_options;

  // extra data we add to the header for service connections
  std::map<std::string, std::string> service_header;
  service_header["component instance"] = config["Name"].asString();

  if ( config["Logging"]["Component Logger"]["Enabled"].asBool() ) {
    logger->enable_logging();
    logger->create_file(workingDir+"/"+config["Logging"]["Component Logger"]["FileName"].asString());
    logger->set_is_periodic(config["Logging"]["Component Logger"]["Enabled"].asBool());
    logger->set_max_log_unit(config["Logging"]["Component Logger"]["Unit"].asInt());

    ROS_INFO_STREAM("Saving user log to " <<
		    workingDir << "/" <<
		    config["Logging"]["Component Logger"]["FileName"].asString());
  }
  
  if ( config["Logging"]["ROSMOD Logger"]["Enabled"].asBool() ) {
    trace->enable_logging();
    trace->create_file(workingDir+"/"+config["Logging"]["ROSMOD Logger"]["FileName"].asString());
    trace->set_is_periodic(config["Logging"]["ROSMOD Logger"]["Enabled"].asBool());
    trace->set_max_log_unit(config["Logging"]["ROSMOD Logger"]["Unit"].asInt());

    ROS_INFO_STREAM("Saving trace log to " <<
		    workingDir + "/" +
		    config["Logging"]["ROSMOD Logger"]["FileName"].asString());
  }

  // Action Servers
<%
if (compInfo['Action Server_list']) {
  compInfo['Action Server_list'].map(function(srv) {
-%>
  // Action Server - <%- srv.name %>
  // TODO: Add support for callback options (Priority / Deadline) to Action Servers
  this-><%- srv.name %>.registerGoalCallback(
    boost::bind(&<%- compInfo.name %>::<%- srv.name %>_goal_cb, this)
  );
  this-><%- srv.name %>.registerPreemptCallback(
    boost::bind(&<%- compInfo.name %>::<%- srv.name %>_preempt_cb, this)
  );
  this-><%- srv.name %>.initialize(
    nh_,
    "<%- srv.Action.AdvertisedName %>",
    boost::bind(&<%- compInfo.name %>::<%- srv.name %>_execute_cb, this, _1),
    false,  // don't auto-start the action server
    &comp_queue
  );
  this-><%- srv.name %>.start();
<%
    });
}
-%>
  // Action Clients
<%
if (compInfo['Action Client_list']) {
  compInfo['Action Client_list'].map(function(clt) {
-%>
  // Action Client - <%- clt.name %>
  // TODO: Add support for callback options (Priority / Deadline) to Action Client Callbacks
  this-><%- clt.name %>.registerDoneCallback(
      boost::bind(&<%- compInfo.name %>::<%- clt.name %>_done_cb, this, _1, _2)
  );
  this-><%- clt.name %>.registerActiveCallback(
      boost::bind(&<%- compInfo.name %>::<%- clt.name %>_active_cb, this)
  );
  this-><%- clt.name %>.registerFeedbackCallback(
      boost::bind(&<%- compInfo.name %>::<%- clt.name %>_feedback_cb, this, _1)
  );
  this-><%- clt.name %>.initialize(nh_, "<%- clt.Action.AdvertisedName %>", &comp_queue);
  logger->log("DEBUG", "<Action Client><%- clt.name %> connected!");
<%
    });
 }
-%>
  // Servers
<%
if (compInfo.Server_list) {
  compInfo.Server_list.map(function(srv) {
-%>
  // Server - <%- srv.name %>
  advertiseName = "<%- srv.Service.AdvertisedName %>";
  ros::AdvertiseServiceOptions <%- srv.name %>_server_options;
  <%- srv.name %>_server_options = ros::AdvertiseServiceOptions::create<<%- srv.Service.Package %>::<%- srv.Service.TypeName %>>
      (advertiseName.c_str(),
       boost::bind(&<%- compInfo.name %>::<%- srv.name %>_operation, this, _1, _2),
       ros::VoidPtr(),
       &comp_queue);
  this-><%- srv.name %> = nh_.advertiseService(<%- srv.name %>_server_options);
<%
    });
}
-%>
  // Clients
<%
if (compInfo.Client_list) {
  compInfo.Client_list.map(function(clt) {
-%>
  // Client - <%- clt.name %>
  advertiseName = "<%- clt.Service.AdvertisedName %>";
  this-><%- clt.name %> = nh_.serviceClient<<%- clt.Service.Package %>::<%- clt.Service.TypeName %>>(
                                                                                                advertiseName.c_str(),
                                                                                                false, // not persistent
                                                                                                service_header
                                                                                                );//, true); 
  this-><%- clt.name %>.waitForExistence();
  logger->log("DEBUG", "<Client><%- clt.name %> connected!");
<%
    });
 }
-%>
  // Publishers
  bool latching = true;
<%
if (compInfo.Publisher_list) {
  compInfo.Publisher_list.map(function(pub) {
-%>
  // Publisher - <%- pub.name %>
  advertiseName = "<%- pub.Message.AdvertisedName %>";
  latching = <%- pub.Latching ? "true" : "false" %>;
  this-><%- pub.name %> = nh_.advertise<<%- pub.Message.Package %>::<%- pub.Message.TypeName %>>(
                                                                                            advertiseName.c_str(),
                                                                                            1000,
                                                                                            latching
                                                                                            ); 
<%
    });
 }
-%>
  // Subscribers
<%
if (compInfo.Subscriber_list) {
  compInfo.Subscriber_list.map(function(sub) {
-%>
  // Subscriber - <%- sub.name %>
  advertiseName = "<%- sub.Message.AdvertisedName %>";
  ros::SubscribeOptions <%- sub.name %>_options;
  <%- sub.name %>_options = ros::SubscribeOptions::create<<%- sub.Message.Package %>::<%- sub.Message.TypeName %>>
      (advertiseName.c_str(),
       1000,
       boost::bind(&<%- compInfo.name %>::<%- sub.name %>_operation, this, _1),
       ros::VoidPtr(),
       &comp_queue);
  this-><%- sub.name %> = nh_.subscribe(<%- sub.name %>_options);
<%
    });
}
-%>

  // Init Timer
  timer_options = 
    ros::TimerOptions
    (ros::Duration(-1),
     boost::bind(&<%- compInfo.name %>::init_timer_operation, this, _1),
     &comp_queue,
     true,
     false); 
  this->init_timer = nh_.createTimer(timer_options);
  this->init_timer.start();

  // Timers
<%
if (compInfo.Timer_list) {
  compInfo.Timer_list.map(function(tmr) {
-%>
  // Component Timer - <%- tmr.name %>
  isOneShot = (config["Timers"]["<%- tmr.name %>"]["Period"].asFloat() <= 0) ? true : false;
  timer_options = 
    ros::TimerOptions
    (ros::Duration(config["Timers"]["<%- tmr.name %>"]["Period"].asFloat()),
     boost::bind(&<%- compInfo.name %>::<%- tmr.name %>_operation, this, _1),
     &comp_queue,
     isOneShot,
     false);

  this-><%- tmr.name %> = nh_.createTimer(timer_options);
<%
    });
 }
-%>
<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
      // HFSM Timer
      // NEED TO FIGURE OUT HOW TO SPECIFY PRIORITY FOR THE HFSM TIMER IN THE MODEL
      ros::Duration hfsmPeriod = ros::Duration( 0 );
      isOneShot = false;
      timer_options = 
        ros::TimerOptions
        (hfsmPeriod,
         boost::bind(&<%- compInfo.name %>::<%- hfsm.sanitizedName %>_HFSM_timer_operation, this, _1),
         &comp_queue,
         isOneShot,
         false);
      <%- hfsm.sanitizedName %>_HFSM_timer = nh_.createTimer(timer_options);
      <%- hfsm.sanitizedName %>_HFSM_timer.start();
<%
  });
}
-%>
  // Start the timers
<%
if (compInfo.Timer_list) {
  compInfo.Timer_list.map(function(tmr) {
-%>
  this-><%- tmr.name %>.start();
<%
    });
 }
-%>
}

extern "C" {
  Component *maker(Json::Value &config) {
    return new <%- compInfo.name %>(config);
  }
}

