diff --git a/ndn-traffic-server.cpp b/ndn-traffic-server.cpp
index 38b3461..0e64a39 100644
--- a/ndn-traffic-server.cpp
+++ b/ndn-traffic-server.cpp
@@ -1,538 +1,451 @@
-/**
- *
- * Copyright (C) 2014 University of Arizona.
- * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
- *
- */
-
-#include <sstream>
-#include <boost/asio.hpp>
-#include <boost/filesystem.hpp>
-
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-
-using namespace ndn;
-
-class Logger
-{
-public:
-
-  Logger()
-  {
-    logLocation_ = "";
-  }
-
-  void
-  shutdownLogger()
-  {
-    if (logFile_.is_open())
-    {
-      log("Terminating Logging Operations" , true, true);
-      logFile_.close();
-    }
-  }
-
-  static std::string
-  getTimestamp()
-  {
-    boost::posix_time::ptime now;
-    now = boost::posix_time::second_clock::local_time();
-    return to_simple_string(now);
-  }
-
-  void
-  log( std::string logLine, bool printTime, bool printToConsole )
-  {
-    if( logLocation_.length() > 0 )
-    {
-      if (printTime)
-        logFile_ << getTimestamp() << " - ";
-      logFile_ << logLine << std::endl;
-      logFile_.flush();
-      if (printToConsole)
-      {
-        if (printTime)
-          std::cout << getTimestamp() << " - ";
-        std::cout << logLine << std::endl;
-      }
-    }
-    else
-    {
-      if (printTime)
-        std::cout << getTimestamp() << " - ";
-      std::cout << logLine << std::endl;
-    }
-  }
-
-  void
-  initializeLog( std::string instanceId )
-  {
-    char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");
-    std::string logFilename;
-    logLocation_ = "";
-    if (variableValue != NULL)
-      logLocation_ = variableValue;
-    if (boost::filesystem::exists(boost::filesystem::path(logLocation_)))
-    {
-      if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_)))
-      {
-        logFilename = logLocation_+"/NDNTrafficServer_"+instanceId+".log";
-        logFile_.open(logFilename.c_str(), std::ofstream::out | std::ofstream::trunc);
-        if (logFile_.is_open())
-          std::cout << "Log File Initialized: " << logFilename << std::endl;
-        else
-        {
-          std::cout << "ERROR - Unable To Initialize A Log File At: " << logLocation_ << std::endl
-                    << "Using Default Output For Logging." << std::endl;
-          logLocation_ = "";
-        }
-      }
-      else
-      {
-        std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder." << std::endl
-                  << "Using Default Output For Logging." << std::endl;
-        logLocation_ = "";
-      }
-    }
-    else
-    {
-      std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set." << std::endl
-                << "Using Default Output For Logging." << std::endl;
-      logLocation_ = "";
-    }
-  }
-
-private:
-
-  std::string logLocation_;
-  std::ofstream logFile_;
-
-};
-
-
-class NdnTrafficServer
-{
-public:
-
-  NdnTrafficServer( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_), keyChain_()
-  {
-    std::srand(std::time(0));
-    instanceId_ = toString(std::rand());
-    programName_ = programName;
-    contentDelayTime_ = getDefaultContentDelayTime();
-    totalRegistrationsFailed_ = 0;
-    configurationFile_ = "";
-    totalInterestReceived_ = 0;
-  }
-
-  class DataTrafficConfiguration
-  {
-  public:
-
-    DataTrafficConfiguration()
-    {
-      name = "";
-      contentType = -1;
-      freshnessPeriod = -1;
-      contentBytes = -1;
-      content = "";
-      totalInterestReceived = 0;
-    }
-
-    void
-    printTrafficConfiguration( Logger& logger )
-    {
-      std::string detail;
-      detail = "";
-      if (name != "")
-        detail += "Name="+name+", ";
-      if (contentType >= 0)
-        detail += "ContentType="+toString(contentType)+", ";
-      if (freshnessPeriod >= 0)
-        detail += "FreshnessPeriod="+toString(freshnessPeriod)+", ";
-      if (contentBytes >= 0)
-        detail += "ContentBytes="+toString(contentBytes)+", ";
-      if (content != "")
-        detail += "Content="+content+", ";
-      if (detail.length() >= 0)
-        detail = detail.substr(0, detail.length()-2);
-      logger.log(detail, false, false);
-    }
-
-
-    bool
-    extractParameterValue( std::string detail, std::string& parameter, std::string& value )
-    {
-      int i;
-      std::string allowedCharacters = ":/+._-%";
-      parameter = "";
-      value = "";
-      i = 0;
-      while (detail[i] != '=' && i < detail.length())
-      {
-        parameter += detail[i];
-        i++;
-      }
-      if (i == detail.length())
-        return false;
-      i++;
-      while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length())
-      {
-        value += detail[i];
-        i++;
-      }
-      if(parameter == "" || value == "")
-        return false;
-      return true;
-    }
-
-    bool
-    processConfigurationDetail( std::string detail, Logger& logger, int lineNumber )
-    {
-      std::string parameter, value;
-      if (extractParameterValue(detail, parameter, value))
-      {
-        if (parameter == "Name")
-          name = value;
-        else if (parameter == "ContentType")
-          contentType = toInteger(value);
-        else if (parameter == "FreshnessPeriod")
-          freshnessPeriod = toInteger(value);
-        else if (parameter == "ContentBytes")
-          contentBytes = toInteger(value);
-        else if (parameter == "Content")
-          content = value;
-        else
-          logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true);
-      }
-      else
-      {
-        logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true);
-        return false;
-      }
-      return true;
-    }
-
-    bool
-    checkTrafficDetailCorrectness()
-    {
-      return true;
-    }
-
-    std::string name;
-    int contentType;
-    int freshnessPeriod;
-    int contentBytes;
-    std::string content;
-    int totalInterestReceived;
-
-  };
-
-  std::string
-  getDefaultContent()
-  {
-    return "";
-  }
-
-  static std::string
-  toString( int integerValue )
-  {
-    std::stringstream stream;
-    stream << integerValue;
-    return stream.str();
-  }
-
-  static int
-  toInteger( std::string stringValue )
-  {
-    int integerValue;
-    std::stringstream stream(stringValue);
-    stream >> integerValue;
-    return integerValue;
-  }
-
-  void
-  usage()
-  {
-
-    std::cout << "\nUsage: " << programName_ << " [options] <Traffic_Configuration_File>\n"
-        "Respond to Interest as per provided Traffic Configuration File\n"
-        "Multiple Prefixes can be configured for handling.\n"
-        "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
-        "  [-d interval] - set delay before responding to interest in milliseconds (minimum "
-        << getDefaultContentDelayTime() << " milliseconds)\n"
-        "  [-h] - print help and exit\n\n";
-    exit(1);
-
-  }
-
-  int
-  getDefaultContentDelayTime()
-  {
-    return 0;
-  }
-
-  void
-  setContentDelayTime( int contentDelayTime )
-  {
-    if (contentDelayTime < 0)
-      usage();
-    contentDelayTime_ = contentDelayTime;
-  }
-
-  void
-  setConfigurationFile( char* configurationFile )
-  {
-    configurationFile_ = configurationFile;
-  }
-
-  void
-  signalHandler()
-  {
-    logger_.shutdownLogger();
-    face_.shutdown();
-    ioService_.reset();
-    logStatistics();
-    exit(1);
-  }
-
-  void
-  logStatistics()
-  {
-    int patternId;
-    logger_.log("\n\n== Interest Traffic Report ==\n", false, true);
-    logger_.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);
-    logger_.log("Total Interests Received    = "+toString(totalInterestReceived_), false, true);
-    for (patternId=0; patternId<trafficPattern_.size(); patternId++)
-    {
-      logger_.log("\nTraffic Pattern Type #"+toString(patternId+1), false, true);
-      trafficPattern_[patternId].printTrafficConfiguration(logger_);
-      logger_.log("Total Interests Received    = "+toString(trafficPattern_[patternId].totalInterestReceived)+"\n", false, true);
-    }
-  }
-
-  bool
-  checkTrafficPatternCorrectness()
-  {
-    return true;
-  }
-
-  void
-  analyzeConfigurationFile()
-  {
-    int patternId;
-    int lineNumber;
-    bool skipLine;
-    std::string patternLine;
-    std::ifstream patternFile;
-    logger_.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
-    patternFile.open(configurationFile_.c_str());
-    if (patternFile.is_open())
-    {
-      patternId = 0;
-      lineNumber = 0;
-      while (getline(patternFile, patternLine))
-      {
-        lineNumber++;
-        if (std::isalpha(patternLine[0]))
-        {
-          DataTrafficConfiguration dataData;
-          skipLine = false;
-          patternId++;
-          if (dataData.processConfigurationDetail(patternLine, logger_, lineNumber))
-          {
-            while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
-            {
-              lineNumber++;
-              if (!dataData.processConfigurationDetail(patternLine, logger_, lineNumber))
-              {
-                skipLine = true;
-                break;
-              }
-            }
-            lineNumber++;
-          }
-          else
-            skipLine = true;
-          if( !skipLine )
-          {
-            if (dataData.checkTrafficDetailCorrectness())
-              trafficPattern_.push_back(dataData);
-          }
-        }
-      }
-      patternFile.close();
-      if (!checkTrafficPatternCorrectness())
-      {
-        logger_.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
-        logger_.shutdownLogger();
-        exit(1);
-      }
-      logger_.log("Traffic Configuration File Processing Completed\n", true, false);
-      for (patternId = 0; patternId < trafficPattern_.size(); patternId++)
-      {
-        logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
-        trafficPattern_[patternId].printTrafficConfiguration(logger_);
-        logger_.log("", false, false);
-      }
-    }
-    else
-    {
-      logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
-      logger_.shutdownLogger();
-      exit(1);
-    }
-  }
-
-  void
-  initializeTrafficConfiguration()
-  {
-    if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
-    {
-      if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
-      {
-        analyzeConfigurationFile();
-      }
-      else
-      {
-        logger_.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
-        logger_.shutdownLogger();
-        exit(1);
-      }
-    }
-    else
-    {
-      logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
-      logger_.shutdownLogger();
-      exit(1);
-    }
-  }
-
-  static std::string
-  getRandomByteString( int randomSize )
-  {
-    int i;
-    std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
-    std::string randomData;
-    for (i=0; i<randomSize; i++)
-      randomData += characterSet[std::rand() % characterSet.length()];
-    return randomData;
-  }
-
-  void
-  onInterest( const Name& name, const Interest& interest, int patternId )
-  {
-    std::string content, logLine;
-    content = "";
-    logLine = "";
-
-    Data data(interest.getName());
-    if (trafficPattern_[patternId].contentType >= 0)
-      data.setContentType(trafficPattern_[patternId].contentType);
-    if (trafficPattern_[patternId].freshnessPeriod >= 0)
-      data.setFreshnessPeriod(trafficPattern_[patternId].freshnessPeriod);
-    if (trafficPattern_[patternId].contentBytes >= 0)
-      content = getRandomByteString(trafficPattern_[patternId].contentBytes);
-    if (trafficPattern_[patternId].content != "")
-      content = trafficPattern_[patternId].content;
-    data.setContent((const uint8_t*)content.c_str(), content.length());
-    keyChain_.sign(data);
-    totalInterestReceived_++;
-    trafficPattern_[patternId].totalInterestReceived++;
-    logLine += "Interest Received          - PatternType="+toString(patternId+1);
-    logLine += ", GlobalID="+toString(totalInterestReceived_);
-    logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestReceived);
-    logLine += ", Name="+trafficPattern_[patternId].name;
-    logger_.log(logLine, true, false);
-    usleep(contentDelayTime_*1000);
-    face_.put(data);
-  }
-
-  void
-  onRegisterFailed( const ndn::Name& prefix, const std::string& reason, int patternId )
-  {
-    std::string logLine;
-    logLine = "";
-    logLine += "Prefix Registration Failed - PatternType="+toString(patternId+1);
-    logLine += ", Name="+trafficPattern_[patternId].name;
-    logger_.log(logLine, true, true);
-    totalRegistrationsFailed_++;
-    if (totalRegistrationsFailed_ == trafficPattern_.size())
-      signalHandler();
-  }
-
-  void
-  initialize()
-  {
-    boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
-    signalSet.async_wait(boost::bind(&NdnTrafficServer::signalHandler, this));
-    logger_.initializeLog(instanceId_);
-    initializeTrafficConfiguration();
-
-    int patternId;
-    for (patternId=0; patternId<trafficPattern_.size(); patternId++ )
-    {
-      face_.setInterestFilter(  trafficPattern_[patternId].name,
-                                func_lib::bind( &NdnTrafficServer::onInterest,
-                                                this, _1, _2,
-                                                patternId),
-                                func_lib::bind( &NdnTrafficServer::onRegisterFailed,
-                                                this, _1, _2,
-                                                patternId));
-    }
-
-    try {
-      face_.processEvents();
-    }
-    catch(std::exception &e) {
-      logger_.log("ERROR: "+(std::string)e.what(), true, true);
-      logger_.shutdownLogger();
-    }
-  }
-
-private:
-
-  KeyChain keyChain_;
-  std::string programName_;
-  std::string instanceId_;
-  int contentDelayTime_;
-  int totalRegistrationsFailed_;
-  Logger logger_;
-  std::string configurationFile_;
-  ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
-  Face face_;
-  std::vector<DataTrafficConfiguration> trafficPattern_;
-  int totalInterestReceived_;
-
-};
-
-int main( int argc, char* argv[] )
-{
-  int option;
-  NdnTrafficServer ndnTrafficServer (argv[0]);
-  while ((option = getopt(argc, argv, "hd:")) != -1) {
-    switch (option) {
-      case 'h'  :
-        ndnTrafficServer.usage();
-        break;
-      case 'd'  :
-        ndnTrafficServer.setContentDelayTime(atoi(optarg));
-        break;
-      default   :
-        ndnTrafficServer.usage();
-        break;
-    }
-  }
-
-  argc -= optind;
-  argv += optind;
-
-  if (argv[0] == NULL)
-    ndnTrafficServer.usage();
-
-  ndnTrafficServer.setConfigurationFile(argv[0]);
-  ndnTrafficServer.initialize();
-
-  return 0;
-}
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2014 University of Arizona.
+ *
+ * GNU 3.0 License, see the LICENSE file for more information
+ *
+ * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ */
+
+#include <sstream>
+#include <boost/asio.hpp>
+#include <boost/filesystem.hpp>
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+
+#include "logger.hpp"
+
+namespace ndn {
+
+class NdnTrafficServer
+{
+public:
+  
+  NdnTrafficServer( char* programName )
+    : m_logger("NDNTrafficServer")
+    , ioService_(new boost::asio::io_service)
+    , face_(ioService_)
+    , keyChain_()
+  {
+    std::srand(std::time(0));
+    instanceId_ = toString(std::rand());
+    programName_ = programName;
+    contentDelayTime_ = getDefaultContentDelayTime();
+    totalRegistrationsFailed_ = 0;
+    configurationFile_ = "";
+    totalInterestReceived_ = 0;
+  }
+
+  class DataTrafficConfiguration
+  {
+  public:
+
+    DataTrafficConfiguration()
+    {
+      name = "";
+      contentType = -1;
+      freshnessPeriod = -1;
+      contentBytes = -1;
+      content = "";
+      totalInterestReceived = 0;
+    }
+
+    void
+    printTrafficConfiguration( Logger& logger )
+    {
+      std::string detail;
+      detail = "";
+      if (name != "")
+        detail += "Name="+name+", ";
+      if (contentType >= 0)
+        detail += "ContentType="+toString(contentType)+", ";
+      if (freshnessPeriod >= 0)
+        detail += "FreshnessPeriod="+toString(freshnessPeriod)+", ";
+      if (contentBytes >= 0)
+        detail += "ContentBytes="+toString(contentBytes)+", ";
+      if (content != "")
+        detail += "Content="+content+", ";
+      if (detail.length() >= 2)
+        detail = detail.substr(0, detail.length()-2);
+      logger.log(detail, false, false);
+    }
+
+
+    bool
+    extractParameterValue( std::string detail, std::string& parameter, std::string& value )
+    {
+      int i;
+      std::string allowedCharacters = ":/+._-%";
+      parameter = "";
+      value = "";
+      i = 0;
+      while (detail[i] != '=' && i < detail.length())
+        {
+          parameter += detail[i];
+          i++;
+        }
+      if (i == detail.length())
+        return false;
+      i++;
+      while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length())
+        {
+          value += detail[i];
+          i++;
+        }
+      if(parameter == "" || value == "")
+        return false;
+      return true;
+    }
+
+    bool
+    processConfigurationDetail( std::string detail, Logger& logger, int lineNumber )
+    {
+      std::string parameter, value;
+      if (extractParameterValue(detail, parameter, value))
+        {
+          if (parameter == "Name")
+            name = value;
+          else if (parameter == "ContentType")
+            contentType = toInteger(value);
+          else if (parameter == "FreshnessPeriod")
+            freshnessPeriod = toInteger(value);
+          else if (parameter == "ContentBytes")
+            contentBytes = toInteger(value);
+          else if (parameter == "Content")
+            content = value;
+          else
+            logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true);
+        }
+      else
+        {
+          logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true);
+          return false;
+        }
+      return true;
+    }
+
+    bool
+    checkTrafficDetailCorrectness()
+    {
+      return true;
+    }
+
+    std::string name;
+    int contentType;
+    int freshnessPeriod;
+    int contentBytes;
+    std::string content;
+    int totalInterestReceived;
+
+  };
+
+  std::string
+  getDefaultContent()
+  {
+    return "";
+  }
+
+  static std::string
+  toString( int integerValue )
+  {
+    std::stringstream stream;
+    stream << integerValue;
+    return stream.str();
+  }
+
+  static int
+  toInteger( std::string stringValue )
+  {
+    int integerValue;
+    std::stringstream stream(stringValue);
+    stream >> integerValue;
+    return integerValue;
+  }
+
+  void
+  usage()
+  {
+
+    std::cout << "\nUsage: " << programName_ << " [options] <Traffic_Configuration_File>\n"
+      "Respond to Interest as per provided Traffic Configuration File\n"
+      "Multiple Prefixes can be configured for handling.\n"
+      "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
+      "  [-d interval] - set delay before responding to interest in milliseconds (minimum "
+              << getDefaultContentDelayTime() << " milliseconds)\n"
+      "  [-h] - print help and exit\n\n";
+    exit(1);
+
+  }
+
+  int
+  getDefaultContentDelayTime()
+  {
+    return 0;
+  }
+
+  void
+  setContentDelayTime( int contentDelayTime )
+  {
+    if (contentDelayTime < 0)
+      usage();
+    contentDelayTime_ = contentDelayTime;
+  }
+
+  void
+  setConfigurationFile( char* configurationFile )
+  {
+    configurationFile_ = configurationFile;
+  }
+
+  void
+  signalHandler()
+  {
+    m_logger.shutdownLogger();
+    face_.shutdown();
+    ioService_.reset();
+    logStatistics();
+    exit(1);
+  }
+
+  void
+  logStatistics()
+  {
+    int patternId;
+    m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
+    m_logger.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);
+    m_logger.log("Total Interests Received    = "+toString(totalInterestReceived_), false, true);
+    for (patternId=0; patternId<trafficPattern_.size(); patternId++)
+      {
+        m_logger.log("\nTraffic Pattern Type #"+toString(patternId+1), false, true);
+        trafficPattern_[patternId].printTrafficConfiguration(m_logger);
+        m_logger.log("Total Interests Received    = "+toString(trafficPattern_[patternId].totalInterestReceived)+"\n", false, true);
+      }
+  }
+
+  bool
+  checkTrafficPatternCorrectness()
+  {
+    return true;
+  }
+
+  void
+  analyzeConfigurationFile()
+  {
+    int patternId;
+    int lineNumber;
+    bool skipLine;
+    std::string patternLine;
+    std::ifstream patternFile;
+    m_logger.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
+    patternFile.open(configurationFile_.c_str());
+    if (patternFile.is_open())
+      {
+        patternId = 0;
+        lineNumber = 0;
+        while (getline(patternFile, patternLine))
+          {
+            lineNumber++;
+            if (std::isalpha(patternLine[0]))
+              {
+                DataTrafficConfiguration dataData;
+                skipLine = false;
+                patternId++;
+                if (dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
+                  {
+                    while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
+                      {
+                        lineNumber++;
+                        if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
+                          {
+                            skipLine = true;
+                            break;
+                          }
+                      }
+                    lineNumber++;
+                  }
+                else
+                  skipLine = true;
+                if( !skipLine )
+                  {
+                    if (dataData.checkTrafficDetailCorrectness())
+                      trafficPattern_.push_back(dataData);
+                  }
+              }
+          }
+        patternFile.close();
+        if (!checkTrafficPatternCorrectness())
+          {
+            m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
+            m_logger.shutdownLogger();
+            exit(1);
+          }
+        m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
+        for (patternId = 0; patternId < trafficPattern_.size(); patternId++)
+          {
+            m_logger.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
+            trafficPattern_[patternId].printTrafficConfiguration(m_logger);
+            m_logger.log("", false, false);
+          }
+      }
+    else
+      {
+        m_logger.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
+        m_logger.shutdownLogger();
+        exit(1);
+      }
+  }
+
+  void
+  initializeTrafficConfiguration()
+  {
+    if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
+      {
+        if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
+          {
+            analyzeConfigurationFile();
+          }
+        else
+          {
+            m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
+            m_logger.shutdownLogger();
+            exit(1);
+          }
+      }
+    else
+      {
+        m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
+        m_logger.shutdownLogger();
+        exit(1);
+      }
+  }
+
+  static std::string
+  getRandomByteString( int randomSize )
+  {
+    int i;
+    std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
+    std::string randomData;
+    for (i=0; i<randomSize; i++)
+      randomData += characterSet[std::rand() % characterSet.length()];
+    return randomData;
+  }
+
+  void
+  onInterest( const Name& name, const Interest& interest, int patternId )
+  {
+    std::string content, logLine;
+    content = "";
+    logLine = "";
+
+    Data data(interest.getName());
+    if (trafficPattern_[patternId].contentType >= 0)
+      data.setContentType(trafficPattern_[patternId].contentType);
+    if (trafficPattern_[patternId].freshnessPeriod >= 0)
+      data.setFreshnessPeriod(trafficPattern_[patternId].freshnessPeriod);
+    if (trafficPattern_[patternId].contentBytes >= 0)
+      content = getRandomByteString(trafficPattern_[patternId].contentBytes);
+    if (trafficPattern_[patternId].content != "")
+      content = trafficPattern_[patternId].content;
+    data.setContent((const uint8_t*)content.c_str(), content.length());
+    keyChain_.sign(data);
+    totalInterestReceived_++;
+    trafficPattern_[patternId].totalInterestReceived++;
+    logLine += "Interest Received          - PatternType="+toString(patternId+1);
+    logLine += ", GlobalID="+toString(totalInterestReceived_);
+    logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestReceived);
+    logLine += ", Name="+trafficPattern_[patternId].name;
+    m_logger.log(logLine, true, false);
+    usleep(contentDelayTime_*1000);
+    face_.put(data);
+  }
+
+  void
+  onRegisterFailed( const ndn::Name& prefix, const std::string& reason, int patternId )
+  {
+    std::string logLine;
+    logLine = "";
+    logLine += "Prefix Registration Failed - PatternType="+toString(patternId+1);
+    logLine += ", Name="+trafficPattern_[patternId].name;
+    m_logger.log(logLine, true, true);
+    totalRegistrationsFailed_++;
+    if (totalRegistrationsFailed_ == trafficPattern_.size())
+      signalHandler();
+  }
+
+  void
+  initialize()
+  {
+    boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
+    signalSet.async_wait(boost::bind(&NdnTrafficServer::signalHandler, this));
+    m_logger.initializeLog(instanceId_);
+    initializeTrafficConfiguration();
+
+    int patternId;
+    for (patternId=0; patternId<trafficPattern_.size(); patternId++ )
+      {
+        face_.setInterestFilter(  trafficPattern_[patternId].name,
+                                  func_lib::bind( &NdnTrafficServer::onInterest,
+                                                  this, _1, _2,
+                                                  patternId),
+                                  func_lib::bind( &NdnTrafficServer::onRegisterFailed,
+                                                  this, _1, _2,
+                                                  patternId));
+      }
+
+    try {
+      face_.processEvents();
+    }
+    catch(std::exception &e) {
+      m_logger.log("ERROR: "+(std::string)e.what(), true, true);
+      m_logger.shutdownLogger();
+    }
+  }
+
+private:
+
+  KeyChain keyChain_;
+  std::string programName_;
+  std::string instanceId_;
+  int contentDelayTime_;
+  int totalRegistrationsFailed_;
+  Logger m_logger;
+  std::string configurationFile_;
+  ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
+  Face face_;
+  std::vector<DataTrafficConfiguration> trafficPattern_;
+  int totalInterestReceived_;
+
+};
+
+} // namespace ndn
+
+int main( int argc, char* argv[] )
+{
+  int option;
+  ndn::NdnTrafficServer ndnTrafficServer (argv[0]);
+  while ((option = getopt(argc, argv, "hd:")) != -1) {
+    switch (option) {
+    case 'h'  :
+      ndnTrafficServer.usage();
+      break;
+    case 'd'  :
+      ndnTrafficServer.setContentDelayTime(atoi(optarg));
+      break;
+    default   :
+      ndnTrafficServer.usage();
+      break;
+    }
+  }
+
+  argc -= optind;
+  argv += optind;
+
+  if (argv[0] == NULL)
+    ndnTrafficServer.usage();
+
+  ndnTrafficServer.setConfigurationFile(argv[0]);
+  ndnTrafficServer.initialize();
+
+  return 0;
+}
