diff --git a/ndn-traffic-server.cpp b/ndn-traffic-server.cpp
index 4b12510..e059bbe 100644
--- a/ndn-traffic-server.cpp
+++ b/ndn-traffic-server.cpp
@@ -14,25 +14,242 @@
 
 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_)
+  NdnTrafficServer( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_), keyChain_()
   {
-    std::stringstream randomId;
     std::srand(std::time(0));
-    randomId << std::rand();
-    instanceId_ = randomId.str();
+    instanceId_ = toString(std::rand());
     programName_ = programName;
     contentDelayTime_ = getDefaultContentDelayTime();
-    logLocation_ = "";
+    totalRegistrationsFailed_ = 0;
     configurationFile_ = "";
+    totalInterestReceived_ = 0;
   }
 
-  NdnTrafficServer()
-  : keyChain_()
+  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
@@ -66,44 +283,174 @@
   void
   signalHandler()
   {
+    logger_.shutdownLogger();
     face_.shutdown();
     ioService_.reset();
+    logStatistics();
     exit(1);
   }
 
   void
-  initializeLog()
+  logStatistics()
   {
-    char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");
-    if (variableValue != NULL)
-      logLocation_ = variableValue;
-
-    if (boost::filesystem::exists(boost::filesystem::path(logLocation_)))
+    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++)
     {
-      if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_)))
+      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))
       {
-        logLocation_ += "/NDNTrafficServer_"+instanceId_+".log";
-        std::cout << "Log File Initialized: " << logLocation_ << std::endl;
+        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);
+          }
+        }
       }
-      else
+      patternFile.close();
+      if (!checkTrafficPatternCorrectness())
       {
-        std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder.\n"
-                     "Using Default Output For Logging." << std::endl;
-        logLocation_ = "";
+        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
     {
-      std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set.\n"
-                   "Using Default Output For Logging." << std::endl;
-      logLocation_ = "";
+      logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
+      logger_.shutdownLogger();
+      exit(1);
     }
   }
 
   void
   initializeTrafficConfiguration()
   {
-    std::cout << "Traffic Configuration File: " << configurationFile_ << std::endl;
+    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          - PatternID="+toString(patternId);
+    logLine += ", GlobalID="+toString(totalInterestReceived_);
+    logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestReceived);
+    logLine += ", Name="+trafficPattern_[patternId].name;
+    logger_.log(logLine, true, false);
+    face_.put(data);
+  }
+
+  void
+  onRegisterFailed( const ndn::Name& prefix, const std::string& reason, int patternId )
+  {
+    std::string logLine;
+    logLine = "";
+    logLine += "Prefix Registration Failed - PatternID="+toString(patternId);
+    logLine += ", Name="+trafficPattern_[patternId].name;
+    logger_.log(logLine, true, true);
+    totalRegistrationsFailed_++;
+    if (totalRegistrationsFailed_ == trafficPattern_.size())
+      signalHandler();
   }
 
   void
@@ -111,20 +458,43 @@
   {
     boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
     signalSet.async_wait(boost::bind(&NdnTrafficServer::signalHandler, this));
-    initializeLog();
+    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_;
-  std::string logLocation_;
+  int totalRegistrationsFailed_;
+  Logger logger_;
   std::string configurationFile_;
   ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
   Face face_;
-  std::string instanceId_;
+  std::vector<DataTrafficConfiguration> trafficPattern_;
+  int totalInterestReceived_;
 
 };
 
