diff --git a/src/logger.hpp b/src/logger.hpp
new file mode 100644
index 0000000..706c6df
--- /dev/null
+++ b/src/logger.hpp
@@ -0,0 +1,117 @@
+/* -*- 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>
+ */
+
+#ifndef NTG_LOGGER_HPP
+#define NTG_LOGGER_HPP
+
+#include <string>
+#include <boost/filesystem.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+namespace ndn {
+
+class Logger
+{
+public:
+  Logger(const std::string& module)
+    : m_module(module)
+  {
+  }
+
+  void
+  shutdownLogger()
+  {
+    if (m_logFile.is_open())
+      {
+        log("Terminating Logging Operations" , true, true);
+        m_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(const std::string& logLine, bool printTime, bool printToConsole)
+  {
+    if( m_logLocation.length() > 0 )
+      {
+        if (printTime)
+          m_logFile << getTimestamp() << " - ";
+        m_logFile << logLine << std::endl;
+        m_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(const std::string& instanceId)
+  {
+    char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");
+    std::string logFilename;
+    m_logLocation = "";
+    if (variableValue != NULL)
+      m_logLocation = variableValue;
+    if (boost::filesystem::exists(boost::filesystem::path(m_logLocation)))
+      {
+        if (boost::filesystem::is_directory(boost::filesystem::path(m_logLocation)))
+          {
+            logFilename = m_logLocation + "/" + m_module + "_" + instanceId + ".log";
+            m_logFile.open(logFilename.c_str(), std::ofstream::out | std::ofstream::trunc);
+            if (m_logFile.is_open())
+              std::cout << "Log File Initialized: " << logFilename << std::endl;
+            else
+              {
+                std::cout << "ERROR - Unable To Initialize A Log File At: "
+                          << m_logLocation << std::endl
+                          << "Using Default Output For Logging." << std::endl;
+                m_logLocation = "";
+              }
+          }
+        else
+          {
+            std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder."
+                      << std::endl
+                      << "Using Default Output For Logging." << std::endl;
+            m_logLocation = "";
+          }
+      }
+    else
+      {
+        std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set." << std::endl
+                  << "Using Default Output For Logging." << std::endl;
+        m_logLocation = "";
+      }
+  }
+
+private:
+  std::string m_module;
+  std::string m_logLocation;
+  std::ofstream m_logFile;
+};
+
+} // namespace ndn
+
+#endif // NTG_LOGGER_HPP
diff --git a/src/ndn-traffic-client.cpp b/src/ndn-traffic-client.cpp
new file mode 100644
index 0000000..135d4ce
--- /dev/null
+++ b/src/ndn-traffic-client.cpp
@@ -0,0 +1,828 @@
+/* -*- 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 <string>
+#include <sstream>
+#include <fstream>
+#include <vector>
+
+#include "logger.hpp"
+
+#include <boost/asio.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/exclude.hpp>
+#include <ndn-cpp-dev/name-component.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+
+namespace ndn {
+
+class NdnTrafficClient
+{
+public:
+  NdnTrafficClient(char* programName)
+    : m_logger("NDNTrafficClient")
+    , ioService_(new boost::asio::io_service)
+    , face_(ioService_)
+    , keyChain_()
+  {
+    std::srand(std::time(0));
+    instanceId_ = toString(std::rand());
+    programName_ = programName;
+    interestInterval_ = getDefaultInterestInterval();
+    interestCount_ = getDefaultInterestCount();
+    configurationFile_ = "";
+    totalInterestSent_ = 0;
+    totalInterestReceived_ = 0;
+    minimumInterestRoundTripTime_ = std::numeric_limits<double>::max();
+    maximumInterestRoundTripTime_ = 0;
+    totalInterestRoundTripTime_ = 0;
+  }
+
+  class InterestTrafficConfiguration
+  {
+  public:
+    InterestTrafficConfiguration()
+    {
+      trafficPercentage = -1;
+      name = "";
+      nameAppendBytes = -1;
+      nameAppendSequenceNumber = -1;
+      minSuffixComponents = -1;
+      maxSuffixComponents = -1;
+      excludeBefore = "";
+      excludeAfter = "";
+      excludeBeforeBytes = -1;
+      excludeAfterBytes = -1;
+      childSelector = -1;
+      mustBeFresh = -1;
+      nonceDuplicationPercentage = -1;
+      scope = -1;
+      interestLifetime = -1;
+      totalInterestSent = 0;
+      totalInterestReceived = 0;
+      minimumInterestRoundTripTime = std::numeric_limits<double>::max();
+      maximumInterestRoundTripTime = 0;
+      totalInterestRoundTripTime = 0;
+      contentInconsistencies = 0;
+      expectedContent = "";
+    }
+
+    void
+    printTrafficConfiguration(Logger& logger)
+    {
+      std::string detail;
+      detail = "";
+      if (trafficPercentage > 0)
+        detail += "TrafficPercentage="+toString(trafficPercentage)+", ";
+      if (name != "")
+        detail += "Name="+name+", ";
+      if (nameAppendBytes > 0)
+        detail += "NameAppendBytes="+toString(nameAppendBytes)+", ";
+      if (nameAppendSequenceNumber > 0)
+        detail += "NameAppendSequenceNumber="+toString(nameAppendSequenceNumber)+", ";
+      if (minSuffixComponents >= 0)
+        detail += "MinSuffixComponents="+toString(minSuffixComponents)+", ";
+      if (maxSuffixComponents >= 0)
+        detail += "MaxSuffixComponents="+toString(maxSuffixComponents)+", ";
+      if (excludeBefore != "")
+        detail += "ExcludeBefore="+excludeBefore+", ";
+      if (excludeAfter != "")
+        detail += "ExcludeAfter="+excludeAfter+", ";
+      if (excludeBeforeBytes > 0)
+        detail += "ExcludeBeforeBytes="+toString(excludeBeforeBytes)+", ";
+      if (excludeAfterBytes > 0)
+        detail += "ExcludeAfterBytes="+toString(excludeAfterBytes)+", ";
+      if (childSelector >= 0)
+        detail += "ChildSelector="+toString(childSelector)+", ";
+      if (mustBeFresh >= 0)
+        detail += "MustBeFresh="+toString(mustBeFresh)+", ";
+      if (nonceDuplicationPercentage > 0)
+        detail += "NonceDuplicationPercentage="+toString(nonceDuplicationPercentage)+", ";
+      if (scope >= 0)
+        detail += "Scope="+toString(scope)+", ";
+      if (interestLifetime >= 0)
+        detail += "InterestLifetime="+toString(interestLifetime)+", ";
+      if (expectedContent != "")
+        detail += "ExpectedContent="+expectedContent+", ";
+      if (detail.length() >= 2)
+        detail = detail.substr(0, detail.length()-2);
+      logger.log(detail, false, false);
+    }
+
+    bool
+    extractParameterValue(const 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(const std::string& detail, Logger& logger, int lineNumber)
+    {
+      std::string parameter, value;
+      if (extractParameterValue(detail, parameter, value))
+        {
+          if (parameter == "TrafficPercentage")
+            trafficPercentage = toInteger(value);
+          else if (parameter == "Name")
+            name = value;
+          else if (parameter == "NameAppendBytes")
+            nameAppendBytes = toInteger(value);
+          else if (parameter == "NameAppendSequenceNumber")
+            nameAppendSequenceNumber = toInteger(value);
+          else if (parameter == "MinSuffixComponents")
+            minSuffixComponents = toInteger(value);
+          else if (parameter == "MaxSuffixComponents")
+            maxSuffixComponents = toInteger(value);
+          else if (parameter == "ExcludeBefore")
+            excludeBefore = value;
+          else if (parameter == "ExcludeAfter")
+            excludeAfter = value;
+          else if (parameter == "ExcludeBeforeBytes")
+            excludeBeforeBytes = toInteger(value);
+          else if (parameter == "ExcludeAfterBytes")
+            excludeAfterBytes = toInteger(value);
+          else if (parameter == "ChildSelector")
+            childSelector = toInteger(value);
+          else if (parameter == "MustBeFresh")
+            mustBeFresh = toInteger(value);
+          else if (parameter == "NonceDuplicationPercentage")
+            nonceDuplicationPercentage = toInteger(value);
+          else if (parameter == "Scope")
+            scope = toInteger(value);
+          else if (parameter == "InterestLifetime")
+            interestLifetime = toInteger(value);
+          else if (parameter == "ExpectedContent")
+            expectedContent = 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;
+    }
+
+    int trafficPercentage;
+    std::string name;
+    int nameAppendBytes;
+    int nameAppendSequenceNumber;
+    int minSuffixComponents;
+    int maxSuffixComponents;
+    std::string excludeBefore;
+    std::string excludeAfter;
+    int excludeBeforeBytes;
+    int excludeAfterBytes;
+    int childSelector;
+    int mustBeFresh;
+    int nonceDuplicationPercentage;
+    int scope;
+    int interestLifetime;
+    int totalInterestSent;
+    int totalInterestReceived;
+    double minimumInterestRoundTripTime;
+    double maximumInterestRoundTripTime;
+    double totalInterestRoundTripTime;
+    int contentInconsistencies;
+    std::string expectedContent;
+  }; // class InterestTrafficConfiguration
+
+  int
+  getDefaultInterestLifetime()
+  {
+    return 4000;
+  }
+
+  static std::string
+  toString(int integerValue)
+  {
+    std::stringstream stream;
+    stream << integerValue;
+    return stream.str();
+  }
+
+  static std::string
+  toString(double doubleValue)
+  {
+    std::stringstream stream;
+    stream << doubleValue;
+    return stream.str();
+  }
+
+  static int
+  toInteger(const std::string& stringValue)
+  {
+    int integerValue;
+    std::stringstream stream(stringValue);
+    stream >> integerValue;
+    return integerValue;
+  }
+
+  void
+  usage()
+  {
+
+    std::cout << "\nUsage: " << programName_ << " [options] <Traffic_Configuration_File>\n"
+      "Generate Interest Traffic as per provided Traffic Configuration File\n"
+      "Interests are continuously generated unless a total number is specified.\n"
+      "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
+      "  [-i interval] - set interest generation interval in milliseconds (minimum "
+              << getDefaultInterestInterval() << " milliseconds)\n"
+      "  [-c count] - set total number of interests to be generated\n"
+      "  [-h] - print help and exit\n\n";
+    exit(1);
+
+  }
+
+  int
+  getDefaultInterestInterval()
+  {
+    return 1000;
+  }
+
+  int
+  getDefaultInterestCount()
+  {
+    return -1;
+  }
+
+  void
+  setInterestInterval( int interestInterval )
+  {
+    if (interestInterval < 0)
+      usage();
+    interestInterval_ = interestInterval;
+  }
+
+  void
+  setInterestCount( int interestCount )
+  {
+    if (interestCount < 0)
+      usage();
+    interestCount_ = interestCount;
+  }
+
+  void
+  setConfigurationFile( char* configurationFile )
+  {
+    configurationFile_ = configurationFile;
+  }
+
+  void
+  signalHandler()
+  {
+    m_logger.shutdownLogger();
+    face_.shutdown();
+    ioService_.reset();
+    logStatistics();
+    exit(1);
+  }
+
+  void
+  logStatistics()
+  {
+    int patternId;
+    double loss, average, inconsistency;
+
+    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 Sent        = " + toString(totalInterestSent_), false, true);
+    m_logger.log("Total Responses Received    = " + toString(totalInterestReceived_), false, true);
+    if (totalInterestSent_ > 0)
+      loss = (totalInterestSent_-totalInterestReceived_)*100.0/totalInterestSent_;
+    else
+      loss = 0;
+    m_logger.log("Total Interest Loss         = " + toString(loss)+"%", false, true);
+    if (totalInterestReceived_ > 0)
+      {
+        average = totalInterestRoundTripTime_/totalInterestReceived_;
+        inconsistency = contentInconsistencies_*100.0/totalInterestReceived_;
+      }
+    else
+      {
+        average = 0;
+        inconsistency = 0;
+      }
+    m_logger.log("Total Data Inconsistency    = " + toString(inconsistency)+"%", false, true);
+    m_logger.log("Total Round Trip Time       = " +
+                 toString(totalInterestRoundTripTime_)+"ms", false, true);
+    m_logger.log("Average Round Trip Time     = " + toString(average)+"ms\n", false, true);
+
+    for (patternId=0; patternId<trafficPattern_.size(); patternId++)
+      {
+        m_logger.log("Traffic Pattern Type #" + toString(patternId+1), false, true);
+        trafficPattern_[patternId].printTrafficConfiguration(m_logger);
+        m_logger.log("Total Interests Sent        = " +
+                     toString(trafficPattern_[patternId].totalInterestSent), false, true);
+        m_logger.log("Total Responses Received    = " +
+                     toString(trafficPattern_[patternId].totalInterestReceived), false, true);
+        if (trafficPattern_[patternId].totalInterestSent > 0)
+          {
+            loss = (trafficPattern_[patternId].totalInterestSent -
+                    trafficPattern_[patternId].totalInterestReceived);
+            loss *= 100.0;
+            loss /= trafficPattern_[patternId].totalInterestSent;
+          }
+        else
+          loss = 0;
+        m_logger.log("Total Interest Loss         = " + toString(loss)+"%", false, true);
+        if (trafficPattern_[patternId].totalInterestReceived > 0)
+          {
+            average = (trafficPattern_[patternId].totalInterestRoundTripTime /
+                       trafficPattern_[patternId].totalInterestReceived);
+            inconsistency = trafficPattern_[patternId].contentInconsistencies;
+            inconsistency = inconsistency * 100.0 / trafficPattern_[patternId].totalInterestReceived;
+          }
+        else
+          {
+            average = 0;
+            inconsistency = 0;
+          }
+        m_logger.log("Total Data Inconsistency    = " + toString(inconsistency)+"%", false, true);
+        m_logger.log("Total Round Trip Time       = " +
+                     toString(trafficPattern_[patternId].totalInterestRoundTripTime)+"ms",
+                     false, true);
+        m_logger.log("Average Round Trip Time     = " + toString(average)+"ms\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]))
+              {
+                InterestTrafficConfiguration interestData;
+                skipLine = false;
+                patternId++;
+                if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
+                  {
+                    while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
+                      {
+                        lineNumber++;
+                        if (!interestData.processConfigurationDetail(patternLine,
+                                                                     m_logger, lineNumber))
+                          {
+                            skipLine = true;
+                            break;
+                          }
+                      }
+                    lineNumber++;
+                  }
+                else
+                  skipLine = true;
+                if( !skipLine )
+                  {
+                    if (interestData.checkTrafficDetailCorrectness())
+                      trafficPattern_.push_back(interestData);
+                  }
+              }
+          }
+        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);
+      }
+  }
+
+  int
+  getOldNonce()
+  {
+    int randomNonceKey;
+    if (nonceList_.size() == 0)
+      return getNewNonce();
+    std::srand(std::time(0));
+    randomNonceKey = std::rand() % nonceList_.size();
+    return nonceList_[randomNonceKey];
+  }
+
+  int
+  getNewNonce()
+  {
+    int randomNonceKey, i;
+    bool isOld;
+    isOld = true;
+    std::srand(std::time(0));
+
+    //Performance Enhancement
+    if (nonceList_.size() > 1000)
+      nonceList_.clear();
+
+    do
+      {
+        randomNonceKey = std::rand();
+        isOld = false;
+        for (i=0; i<nonceList_.size(); i++)
+          if (nonceList_[i] == randomNonceKey)
+            isOld = true;
+      } while(isOld);
+    nonceList_.push_back(randomNonceKey);
+    return randomNonceKey;
+  }
+
+  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
+  onData( ndn::Face &face,
+          const ndn::Interest& interest,
+          ndn::Data& data,
+          int globalReference,
+          int localReference,
+          int patternId,
+          boost::posix_time::ptime sentTime )
+  {
+    double roundTripTime;
+    int receivedContentLength;
+    std::string receivedContent;
+    std::string logLine;
+    logLine = "";
+    logLine += "Data Received      - PatternType="+toString(patternId+1);
+    logLine += ", GlobalID="+toString(globalReference);
+    logLine += ", LocalID="+toString(localReference);
+    logLine += ", Name="+interest.getName().toUri();
+    boost::posix_time::time_duration roundTripDuration;
+    totalInterestReceived_++;
+    trafficPattern_[patternId].totalInterestReceived++;
+    if (trafficPattern_[patternId].expectedContent != "")
+      {
+        receivedContent = (char*)(data.getContent().value());
+        receivedContentLength = data.getContent().value_size();
+        receivedContent = receivedContent.substr(0, receivedContentLength);
+        if (receivedContent != trafficPattern_[patternId].expectedContent)
+          {
+            contentInconsistencies_++;
+            trafficPattern_[patternId].contentInconsistencies++;
+            logLine += ", IsConsistent=No";
+          }
+        else
+          logLine += ", IsConsistent=Yes";
+      }
+    else
+      logLine += ", IsConsistent=NotChecked";
+    m_logger.log(logLine, true, false);
+    roundTripDuration = boost::posix_time::microsec_clock::local_time() - sentTime;
+    roundTripTime = roundTripDuration.total_microseconds()/1000.0;
+    if (minimumInterestRoundTripTime_ > roundTripTime)
+      minimumInterestRoundTripTime_ = roundTripTime;
+    if (maximumInterestRoundTripTime_ < roundTripTime)
+      maximumInterestRoundTripTime_ = roundTripTime;
+    if (trafficPattern_[patternId].minimumInterestRoundTripTime > roundTripTime)
+      trafficPattern_[patternId].minimumInterestRoundTripTime = roundTripTime;
+    if (trafficPattern_[patternId].maximumInterestRoundTripTime < roundTripTime)
+      trafficPattern_[patternId].maximumInterestRoundTripTime = roundTripTime;
+    totalInterestRoundTripTime_ += roundTripTime;
+    trafficPattern_[patternId].totalInterestRoundTripTime += roundTripTime;
+    if (totalInterestSent_ == interestCount_)
+      signalHandler();
+  }
+
+  void
+  onTimeout( ndn::Face &face,
+             const ndn::Interest& interest,
+             int globalReference,
+             int localReference,
+             int patternId)
+  {
+    std::string logLine;
+    logLine = "";
+    logLine += "Interest Timed Out - PatternType="+toString(patternId+1);
+    logLine += ", GlobalID="+toString(globalReference);
+    logLine += ", LocalID="+toString(localReference);
+    logLine += ", Name="+interest.getName().toUri();
+    m_logger.log(logLine, true, false);
+    if (totalInterestSent_ == interestCount_)
+      signalHandler();
+  }
+
+  void
+  generateTraffic( const boost::system::error_code& errorCode,
+                   boost::asio::deadline_timer* deadlineTimer )
+  {
+    if ((interestCount_ < 0) || (totalInterestSent_ < interestCount_))
+      {
+        int trafficKey, patternId, cumulativePercentage;
+        std::srand(std::time(0));
+        trafficKey = std::rand() % 100;
+        cumulativePercentage = 0;
+        for (patternId=0; patternId<trafficPattern_.size(); patternId++)
+          {
+            cumulativePercentage += trafficPattern_[patternId].trafficPercentage;
+            if (trafficKey <= cumulativePercentage)
+              {
+                Name interestName(trafficPattern_[patternId].name);
+                if (trafficPattern_[patternId].nameAppendBytes > 0)
+                  interestName.append(getRandomByteString(trafficPattern_[patternId].nameAppendBytes));
+                if (trafficPattern_[patternId].nameAppendSequenceNumber >= 0)
+                  {
+                    interestName.append(toString(trafficPattern_[patternId].nameAppendSequenceNumber));
+                    trafficPattern_[patternId].nameAppendSequenceNumber++;
+                  }
+                Interest interest(interestName);
+                if (trafficPattern_[patternId].minSuffixComponents >= 0)
+                  interest.setMinSuffixComponents(trafficPattern_[patternId].minSuffixComponents);
+                if (trafficPattern_[patternId].maxSuffixComponents >= 0)
+                  interest.setMaxSuffixComponents(trafficPattern_[patternId].maxSuffixComponents);
+                Exclude exclude;
+                if (trafficPattern_[patternId].excludeBefore != "" &&
+                    trafficPattern_[patternId].excludeAfter != "")
+                  {
+                    exclude.excludeRange(name::Component(trafficPattern_[patternId].excludeAfter),
+                                         name::Component(trafficPattern_[patternId].excludeBefore));
+                    interest.setExclude(exclude);
+                  }
+                else if (trafficPattern_[patternId].excludeBefore != "")
+                  {
+                    exclude.excludeBefore(name::Component(trafficPattern_[patternId].excludeBefore));
+                    interest.setExclude(exclude);
+                  }
+                else if (trafficPattern_[patternId].excludeAfter != "")
+                  {
+                    exclude.excludeAfter(name::Component(trafficPattern_[patternId].excludeAfter));
+                    interest.setExclude(exclude);
+                  }
+                if (trafficPattern_[patternId].excludeBeforeBytes > 0 &&
+                    trafficPattern_[patternId].excludeAfterBytes > 0)
+                  {
+                    exclude.excludeRange(
+                      name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)),
+                      name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
+                    interest.setExclude(exclude);
+                  }
+                else if (trafficPattern_[patternId].excludeBeforeBytes > 0)
+                  {
+                    exclude.excludeBefore(
+                      name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
+                    interest.setExclude(exclude);
+                  }
+                else if (trafficPattern_[patternId].excludeAfterBytes > 0)
+                  {
+                    exclude.excludeAfter(
+                      name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)));
+                    interest.setExclude(exclude);
+                  }
+
+                if (trafficPattern_[patternId].childSelector >= 0)
+                  interest.setChildSelector(trafficPattern_[patternId].childSelector);
+
+                if (trafficPattern_[patternId].mustBeFresh == 0)
+                  interest.setMustBeFresh(false);
+                else if (trafficPattern_[patternId].mustBeFresh > 0)
+                  interest.setMustBeFresh(true);
+                if (trafficPattern_[patternId].nonceDuplicationPercentage > 0)
+                  {
+                    int duplicationKey;
+                    std::srand(std::time(0));
+                    duplicationKey = std::rand() % 100;
+                    if (trafficPattern_[patternId].nonceDuplicationPercentage <= duplicationKey)
+                      interest.setNonce(getOldNonce());
+                    else
+                      interest.setNonce(getNewNonce());
+                  }
+                else
+                  interest.setNonce(getNewNonce());
+                if (trafficPattern_[patternId].scope >= 0)
+                  interest.setScope(trafficPattern_[patternId].scope);
+                if (trafficPattern_[patternId].interestLifetime >= 0)
+                  interest.setInterestLifetime(
+                    time::milliseconds(trafficPattern_[patternId].interestLifetime));
+                else
+                  interest.setInterestLifetime(
+                    time::milliseconds(getDefaultInterestLifetime()));
+                try {
+                  totalInterestSent_++;
+                  trafficPattern_[patternId].totalInterestSent++;
+                  boost::posix_time::ptime sentTime;
+                  sentTime = boost::posix_time::microsec_clock::local_time();
+                  face_.expressInterest(interest,
+                                        bind( &NdnTrafficClient::onData,
+                                              this, boost::ref(face_),
+                                              _1, _2, totalInterestSent_,
+                                              trafficPattern_[patternId].totalInterestSent,
+                                              patternId,
+                                              sentTime),
+                                        bind( &NdnTrafficClient::onTimeout,
+                                              this, boost::ref(face_),
+                                              _1, totalInterestSent_,
+                                              trafficPattern_[patternId].totalInterestSent,
+                                              patternId));
+                  std::string logLine;
+                  logLine = "";
+                  logLine += "Sending Interest   - PatternType="+toString(patternId+1);
+                  logLine += ", GlobalID="+toString(totalInterestSent_);
+                  logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestSent);
+                  logLine += ", Name="+interest.getName().toUri();
+                  m_logger.log(logLine, true, false);
+                  deadlineTimer->expires_at(deadlineTimer->expires_at() +
+                                            boost::posix_time::millisec(interestInterval_));
+                  deadlineTimer->async_wait(bind(&NdnTrafficClient::generateTraffic,
+                                                 this,
+                                                 boost::asio::placeholders::error,
+                                                 deadlineTimer));
+                }
+                catch (std::exception &e) {
+                  m_logger.log("ERROR: "+(std::string)e.what(), true, true);
+                }
+                break;
+              }
+          }
+        if (patternId==trafficPattern_.size())
+          {
+            deadlineTimer->expires_at(deadlineTimer->expires_at() +
+                                      boost::posix_time::millisec(interestInterval_));
+            deadlineTimer->async_wait(bind(&NdnTrafficClient::generateTraffic,
+                                           this,
+                                           boost::asio::placeholders::error,
+                                           deadlineTimer));
+          }
+      }
+  }
+
+  void
+  initialize()
+  {
+    boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
+    signalSet.async_wait(bind(&NdnTrafficClient::signalHandler, this));
+    m_logger.initializeLog(instanceId_);
+    initializeTrafficConfiguration();
+    boost::asio::deadline_timer deadlineTimer(*ioService_,
+                                              boost::posix_time::millisec(interestInterval_));
+    deadlineTimer.async_wait(bind(&NdnTrafficClient::generateTraffic,
+                                  this,
+                                  boost::asio::placeholders::error,
+                                  &deadlineTimer));
+    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 interestInterval_;
+  int interestCount_;
+  Logger m_logger;
+  std::string configurationFile_;
+  ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
+  Face face_;
+  std::vector<InterestTrafficConfiguration> trafficPattern_;
+  std::vector<int> nonceList_;
+  int totalInterestSent_;
+  int totalInterestReceived_;
+  int contentInconsistencies_;
+  double minimumInterestRoundTripTime_;
+  double maximumInterestRoundTripTime_;
+  double totalInterestRoundTripTime_;
+
+};
+
+} // namespace ndn
+
+int main( int argc, char* argv[] )
+{
+  int option;
+  ndn::NdnTrafficClient ndnTrafficClient (argv[0]);
+  while ((option = getopt(argc, argv, "hi:c:")) != -1) {
+    switch (option) {
+    case 'h'  :
+      ndnTrafficClient.usage();
+      break;
+    case 'i'  :
+      ndnTrafficClient.setInterestInterval(atoi(optarg));
+      break;
+    case 'c'  :
+      ndnTrafficClient.setInterestCount(atoi(optarg));
+      break;
+    default   :
+      ndnTrafficClient.usage();
+      break;
+    }
+  }
+
+  argc -= optind;
+  argv += optind;
+
+  if (argv[0] == NULL)
+    ndnTrafficClient.usage();
+
+  ndnTrafficClient.setConfigurationFile(argv[0]);
+  ndnTrafficClient.initialize();
+
+  return 0;
+}
diff --git a/src/ndn-traffic-server.cpp b/src/ndn-traffic-server.cpp
new file mode 100644
index 0000000..0769c69
--- /dev/null
+++ b/src/ndn-traffic-server.cpp
@@ -0,0 +1,462 @@
+/* -*- 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(const 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(const 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(time::milliseconds(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,
+                                bind(&NdnTrafficServer::onInterest,
+                                     this, _1, _2,
+                                     patternId),
+                                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;
+}
