docs: Extending and reorganizing documentation. Adding basic description about forwarding strategies enforcing Interest limits
diff --git a/docs/source/applications.rst b/docs/source/applications.rst
index 97aa326..c62722c 100644
--- a/docs/source/applications.rst
+++ b/docs/source/applications.rst
@@ -1,3 +1,5 @@
+.. _applications:
+
 ndnSIM applications
 ===================
 
@@ -36,9 +38,9 @@
      default: ``"none"``
 
   Specify whether to do randomization for inter-Interest gap or not.  The following variants are currently supported:
-  
+
   - ``"none"``: no randomization
- 
+
   - ``"uniform"``: uniform distribution in range (0, 1/Frequency)
 
   - ``"exponential"``: exponential distribution with mean 1/Frequency
@@ -54,7 +56,7 @@
 .. note::
     Author: Xiaoke Jiang
 
-An app that requests contents (names in the requests) following Zipf-Mandelbrot distribution (number of Content frequency Distribution). 
+An app that requests contents (names in the requests) following Zipf-Mandelbrot distribution (number of Content frequency Distribution).
 This class is a subclass of :ndnsim:`ConsumerCbr`.
 
 .. code-block:: c++
@@ -62,7 +64,7 @@
    // Create application using the app helper
    ndn::AppHelper helper ("ns3::ndn::ConsumerZipfMandelbrot");
 
-``Frequency`` and ``Randomize`` attributes can be used in the same way as in the base :ndnsim:`ConsumerCbr` applications. 
+``Frequency`` and ``Randomize`` attributes can be used in the same way as in the base :ndnsim:`ConsumerCbr` applications.
 
 Additional attributes:
 
@@ -106,7 +108,7 @@
   .. note::
      default: Empty
 
-  Specify exact pattern of Interest packets, specifying when and how many Interest packets should be sent. 
+  Specify exact pattern of Interest packets, specifying when and how many Interest packets should be sent.
   The following example defines that 1 Interest should be requested at time 1s, 5 Interests at time 5s, and 2 Interests at time 10s.:
 
   .. code-block:: c++
@@ -166,7 +168,7 @@
 Custom applications
 +++++++++++++++++++
 
-Applications interact with the core of the system using :ndnsim:`AppFace` realization of Face abstraction. 
+Applications interact with the core of the system using :ndnsim:`AppFace` realization of Face abstraction.
 To simplify implementation of specific NDN application, ndnSIM provides a base :ndnsim:`App` class that takes care of creating :ndnsim:`AppFace` and registering it inside the NDN protocol stack, as well as provides default processing for incoming Interest and Data packets.
 
 .. Base App class
@@ -199,8 +201,8 @@
 
 Example how to use custom app in a scenario (``ndn-simple-with-custom-app.cc``):
 
- .. *      +------+ <-----> (CustomApp1) 
- .. *      | Node | 
+ .. *      +------+ <-----> (CustomApp1)
+ .. *      | Node |
  .. *      +------+ <-----> (CustomApp2)
  .. *
 
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 505ff68..aa315e9 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -25,7 +25,7 @@
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = [ "sphinx.ext.autodoc", "sphinxcontrib.doxylink", "sphinxcontrib.aafig", "sphinxcontrib.googleanalytics" ]
+extensions = [ "sphinx.ext.autodoc", "sphinx.ext.mathjax", "sphinxcontrib.doxylink", "sphinxcontrib.aafig", "sphinxcontrib.googleanalytics" ]
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
diff --git a/docs/source/cs.rst b/docs/source/cs.rst
new file mode 100644
index 0000000..ab5116b
--- /dev/null
+++ b/docs/source/cs.rst
@@ -0,0 +1,230 @@
+.. _content store:
+
+Content Store
++++++++++++++
+
+ndnSIM comes with several different in-memory :ndnsim:`content store <ndn::ContentStore>` implementations, featuring different cache replacement policies.
+
+.. note:
+
+    The default content store uses LRU replacement policity and constrained with 100 cached ContentObjects.
+
+To select a particular content store and configure its capacity, use :ndnsim:`SetContentStore <ndn::StackHelper::SetContentStore>` helper method
+
+Simple content stores
+^^^^^^^^^^^^^^^^^^^^^
+
+Least Recently Used (LRU) (default)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Lru`.
+
+Usage example:
+
+      .. code-block:: c++
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Lru",
+                                    "MaxSize", "10000");
+	 ...
+	 ndnHelper.Install (nodes);
+
+First-In-First-Out (FIFO)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Fifo`
+
+Usage example:
+
+      .. code-block:: c++
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Fifo",
+                                    "MaxSize", "10000");
+	 ...
+	 ndnHelper.Install (nodes);
+
+Random
+~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Random`
+
+Usage example:
+
+      .. code-block:: c++
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Random",
+                                    "MaxSize", "10000");
+	 ...
+	 ndnHelper.Install (nodes);
+
+.. note::
+
+    If ``MaxSize`` parameter is omitted, then will be used a default value (100).
+
+.. note::
+
+    If ``MaxSize`` is set to 0, then no limit on ContentStore will be enforced
+
+
+Content stores with entry lifetime tracking
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In order to evaluate lifetime of the content store entries, the special versions of the content store need to be used:
+
+Least Recently Used (LRU)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Stats::Lru`.
+
+Usage example:
+
+      .. code-block:: c++
+
+         void
+         CacheEntryRemoved (std::string context, Ptr<const ndn::cs::Entry> entry, Time lifetime)
+         {
+             std::cout << entry->GetName () << " " << lifetime.ToDouble (Time::S) << "s" << std::endl;
+         }
+
+         ...
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Stats::Lru",
+                                    "MaxSize", "10000");
+	 ...
+	 ndnHelper.Install (nodes);
+
+         // connect to lifetime trace
+         Config::Connect ("/NodeList/*/$ns3::ndn::cs::Stats::Lru/WillRemoveEntry", MakeCallback (CacheEntryRemoved));
+
+
+First-In-First-Out (FIFO)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Stats::Fifo`.
+
+Usage example:
+
+      .. code-block:: c++
+
+         void
+         CacheEntryRemoved (std::string context, Ptr<const ndn::cs::Entry> entry, Time lifetime)
+         {
+             std::cout << entry->GetName () << " " << lifetime.ToDouble (Time::S) << "s" << std::endl;
+         }
+
+         ...
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Stats::Fifo",
+                                    "MaxSize", "10000");
+	 ...
+	 ndnHelper.Install (nodes);
+
+         // connect to lifetime trace
+         Config::Connect ("/NodeList/*/$ns3::ndn::cs::Stats::Fifo/WillRemoveEntry", MakeCallback (CacheEntryRemoved));
+
+Random
+~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Stats::Random`
+
+Usage example:
+
+      .. code-block:: c++
+
+         void
+         CacheEntryRemoved (std::string context, Ptr<const ndn::cs::Entry> entry, Time lifetime)
+         {
+             std::cout << entry->GetName () << " " << lifetime.ToDouble (Time::S) << "s" << std::endl;
+         }
+
+         ...
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Stats::Random",
+                                    "MaxSize", "10000");
+	 ...
+	 ndnHelper.Install (nodes);
+
+         // connect to lifetime trace
+         Config::Connect ("/NodeList/*/$ns3::ndn::cs::Stats::Random/WillRemoveEntry", MakeCallback (CacheEntryRemoved));
+
+.. _Content Store respecting freshness field of ContentObjects:
+
+Content stores respecting freshness field of ContentObjects
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If simulations need Content Store which respects freshness of ContentObjects, the following versions of content store should be used:
+
+.. note:
+
+    Please note that currently, Freshness granularity is 1 second and maximum value is 65535 second. Value means infinity.
+
+Least Recently Used (LRU)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Freshness::Lru`.
+
+Usage example:
+
+      .. code-block:: c++
+
+         ...
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Freshness::Lru",
+                                    "MaxSize", "10000");
+	 ...
+
+First-In-First-Out (FIFO)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Freshness::Fifo`
+
+Usage example:
+
+      .. code-block:: c++
+
+         ...
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Freshness::Fifo",
+                                    "MaxSize", "10000");
+	 ...
+
+Random
+~~~~~~
+
+Implementation name: :ndnsim:`ndn::cs::Freshness::Random`
+
+Usage example:
+
+      .. code-block:: c++
+
+         ...
+
+         ndnHelper.SetContentStore ("ns3::ndn::cs::Freshness::Random",
+                                    "MaxSize", "10000");
+	 ...
+
+Example
+~~~~~~~
+
+The following example demonstrates a basic usage of a customized content store (``ndn-simple-with-content-freshness.cc``).
+In this scenario two simple consumers (both installed on a consumer node) continually request the same data packet.
+When Data producer specify unlimited freshness, Content keeps getting satisfied from local caches, while if freshness is specified, Interests periodically are getting through to the Data producer.
+
+.. aafig::
+    :aspect: 60
+    :scale: 120
+
+      +----------+                +--------+                +----------+
+      |          |     1Mbps      |        |      1Mbps     |          |
+      | Consumer |<-------------->| Router |<-------------->| Producer |
+      |          |         10ms   |        |         10ms   |          |
+      +----------+                +--------+                +----------+
+
+
+.. literalinclude:: ../../examples/ndn-simple-with-content-freshness.cc
+    :language: c++
+    :linenos:
+    :lines: 20-27,43-
+
+To run this scenario, use the following command::
+
+        NS_LOG=DumbRequester:ndn.cs.Freshness.Lru ./waf --run=ndn-simple-with-content-freshness
diff --git a/docs/source/fw.rst b/docs/source/fw.rst
index dd4176b..45d4f2b 100644
--- a/docs/source/fw.rst
+++ b/docs/source/fw.rst
@@ -1,18 +1,243 @@
+.. _forwarding strategies:
 
 Forwarding Strategies
 =====================
 
-ndnSIM provides simple ways to experiment with custom Interest/Data forwarding strategies. 
+ndnSIM provides simple ways to experiment with custom Interest/Data forwarding strategies.
 A new forwarding strategy can be implement completely different processing or override just specific actions/events of the :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>`.
 Please refer to :ndnsim:`API documentation <ndn::ForwardingStrategy>` of the forwarding strategy interface, which lists all default actions/events.
 
+Available forwarding strategies
++++++++++++++++++++++++++++++++
+
+Basic forwarding strategies
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Flooding
+########
+
+Interests will be forwarded to all available faces available for a route (FIB entry).
+If there are no available GREEN or YELLOW faces, interests is dropped.
+
+Implementation name: :ndnsim:`ns3::ndn::fw::Flooding` (default)
+
+Usage example:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::Flooding");
+	 ...
+	 ndnHelper.Install (nodes);
+
+SmartFlooding
+#############
+
+If GREEN face is available, Interest will be sent to the highest-ranked GREEN face.
+If not, Interest will be forwarded to all available faces available for a route (FIB entry)/
+If there are no available GREEN or YELLOW faces, interests is dropped.
+
+Implementation name :ndnsim:`ns3::ndn::fw::SmartFlooding`
+
+Usage example:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::SmartFlooding");
+	 ...
+	 ndnHelper.Install (nodes);
+
+BestRoute
+#########
+
+If GREEN face is available, Interest will be sent to the highest-ranked GREEN face.
+If not, Interest will be forwarded to the highest-ranked YELLOW face.
+If there are no available GREEN or YELLOW faces, interests is dropped.
+
+Implementation name: :ndnsim:`ns3::ndn::fw::BestRoute`
+
+Usage example:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute");
+	 ...
+	 ndnHelper.Install (nodes);
+
+Strategies with Interest limits
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following strategies enforce different granularities of Interest limits.  Each strategy is an extension of the basic one (custom strategies can also be extended with limits, refer to the source code).
+
+Currently, ndnSIM implements two types of Interest limit enforcements, both based on a Token Bucket approach:
+
+   - :ndnsim:`ns3::ndn::Limits::Window` (default)
+
+        Interest token is borrowed when Interest is send out.  The token is returned only when Interest is satisfied or times out.
+
+   - :ndnsim:`ns3::ndn::Limits::Rate`
+
+        Interest token is borrowed when Interest is send out.  The token is returned periodically based on link capacity.
+
+In both cases, limit is set according to the following equation:
+
+.. math::
+
+    \mathrm{Interest\ Limit} = Delay\ [s] \cdot
+       \frac{\mathrm{Bandwidth\ [Bytes/s]}}
+       {\mathrm{Data\ packet\ size\ [Bytes]} + \mathrm{Interest\ packet\ size\ [Bytes]}}
+
+To configure packet sizes and delay parameters, use the following :ndnsim:`ndn::StackHelper` method:
+
+      .. code-block:: c++
+
+         // ndnHelper.EnableLimits (true, <delay>, <average interest packet size>, <average data packet size>);
+         ndnHelper.EnableLimits (true, Seconds (0.2), 40, 1100);
+	 ...
+	 ndnHelper.Install (nodes);
+
+Usage examples
+##############
+
+Per outgoing Face limits
+%%%%%%%%%%%%%%%%%%%%%%%%
+
+- :ndnsim:`ns3::ndn::fw::Flooding::PerOutFaceLimits`
+
+    With :ndnsim:`Limits::Window`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::Flooding::PerOutFaceLimits"
+                                          "Limit", "ns3::ndn::Limits::Window");
+	 ...
+	 ndnHelper.Install (nodes);
+
+
+    With :ndnsim:`Limits::Rate`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::Flooding::PerOutFaceLimits"
+                                          "Limit", "ns3::ndn::Limits::Rate");
+	 ...
+	 ndnHelper.Install (nodes);
+
+- :ndnsim:`ns3::ndn::fw::SmartFlooding::PerOutFaceLimits`
+
+    With :ndnsim:`Limits::Window`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::SmartFlooding::PerOutFaceLimits"
+                                          "Limit", "ns3::ndn::Limits::Window");
+	 ...
+	 ndnHelper.Install (nodes);
+
+
+    With :ndnsim:`Limits::Rate`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::SmartFlooding::PerOutFaceLimits"
+                                          "Limit", "ns3::ndn::Limits::Rate");
+	 ...
+	 ndnHelper.Install (nodes);
+
+- :ndnsim:`ns3::ndn::fw::BestRoute::PerOutFaceLimits`
+
+    With :ndnsim:`Limits::Window`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute::PerOutFaceLimits"
+                                          "Limit", "ns3::ndn::Limits::Window");
+	 ...
+	 ndnHelper.Install (nodes);
+
+
+    With :ndnsim:`Limits::Rate`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute::PerOutFaceLimits"
+                                          "Limit", "ns3::ndn::Limits::Rate");
+	 ...
+	 ndnHelper.Install (nodes);
+
+
+Per FIB entry, per outgoing face limits
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+- :ndnsim:`ns3::ndn::fw::Flooding::PerOutFaceLimits::PerFibLimits`
+
+    With :ndnsim:`Limits::Window`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::Flooding::PerOutFaceLimits::PerFibLimits"
+                                          "Limit", "ns3::ndn::Limits::Window");
+	 ...
+	 ndnHelper.Install (nodes);
+
+
+    With :ndnsim:`Limits::Rate`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::Flooding::PerOutFaceLimits::PerFibLimits"
+                                          "Limit", "ns3::ndn::Limits::Rate");
+	 ...
+	 ndnHelper.Install (nodes);
+
+- :ndnsim:`ns3::ndn::fw::SmartFlooding::PerOutFaceLimits::PerFibLimits`
+
+    With :ndnsim:`Limits::Window`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::SmartFlooding::PerOutFaceLimits::PerFibLimits"
+                                          "Limit", "ns3::ndn::Limits::Window");
+	 ...
+	 ndnHelper.Install (nodes);
+
+
+    With :ndnsim:`Limits::Rate`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::SmartFlooding::PerOutFaceLimits::PerFibLimits"
+                                          "Limit", "ns3::ndn::Limits::Rate");
+	 ...
+	 ndnHelper.Install (nodes);
+
+- :ndnsim:`ns3::ndn::fw::BestRoute::PerOutFaceLimits::PerFibLimits`
+
+    With :ndnsim:`Limits::Window`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute::PerOutFaceLimits::PerFibLimits"
+                                          "Limit", "ns3::ndn::Limits::Window");
+	 ...
+	 ndnHelper.Install (nodes);
+
+
+    With :ndnsim:`Limits::Rate`:
+
+      .. code-block:: c++
+
+         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute::PerOutFaceLimits::PerFibLimits"
+                                          "Limit", "ns3::ndn::Limits::Rate");
+	 ...
+	 ndnHelper.Install (nodes);
+
 .. _Writing your own custom strategy:
 
 Writing your own custom strategy
 ++++++++++++++++++++++++++++++++
 
-First step in creating your own strategy is to decide which existing strategy you want to extend.  You can either use realize :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>` (:ndnsim:`ndn::ForwardingStrategy::DoPropagateInterest` call must be implemented) or extended one of the available forwarding strategies (:ndnsim:`fw::BestRoute` or :ndnsim:`fw::Flooding`).  
-The following example assumes that we are realizing :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>`. 
+First step in creating your own strategy is to decide which existing strategy you want to extend.  You can either use realize :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>` (:ndnsim:`ndn::ForwardingStrategy::DoPropagateInterest` call must be implemented) or extended one of the available forwarding strategies (:ndnsim:`fw::BestRoute` or :ndnsim:`fw::Flooding`).
+The following example assumes that we are realizing :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>`.
 
 The follwoing are template strategy h/cc files:
 
@@ -27,9 +252,9 @@
    :lines: 1-40,42-50,75-76,115-
    :emphasize-lines: 21,27
 
-After having the template, we can fill the necesasry functionality.  
+After having the template, we can fill the necesasry functionality.
 
-Let us say, that we want Interest be forwarded to first two best-metric faces specified by FIB. 
+Let us say, that we want Interest be forwarded to first two best-metric faces specified by FIB.
 That is, if node has two or more alternative paths to forward the Interests, this Interest will be forwarded to the best two neighbors.
 The following implementation of CustomStrategy::DoPropagateInterest accomplishes the task:
 
diff --git a/docs/source/helpers.rst b/docs/source/helpers.rst
index 3e5f2a9..9ffa3b7 100644
--- a/docs/source/helpers.rst
+++ b/docs/source/helpers.rst
@@ -21,7 +21,7 @@
 Routing
 +++++++
 
-All forwarding strategies require knowledge of where Interests can be forwarded (Forwarding Information Base).  
+All forwarding strategies require knowledge of where Interests can be forwarded (Forwarding Information Base).
 Unlike IP routing, this knowledge may be imprecise, but without such knowledge forwarding strategies will not be able to make any decision and will drop any Interests.
 
 .. note::
@@ -54,27 +54,27 @@
 * install :ndnsim:`special interfaces <GlobalRouter>` on nodes
 
    .. code-block:: c++
-   
+
      NodeContainer nodes;
      ...
      ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
      ndnGlobalRoutingHelper.Install (nodes);
-   
+
 * specify which node exports which prefix using :ndnsim:`GlobalRoutingHelper::AddOrigins`
 
    .. code-block:: c++
-   
+
      Ptr<Node> producer; // producer node that exports prefix
      std::string prefix; // exported prefix
      ...
      ndnGlobalRoutingHelper.AddOrigins (prefix, producer);
-   
+
 * calculate and install FIBs on every node using :ndnsim:`GlobalRoutingHelper::CalculateRoutes`
 
    .. code-block:: c++
-   
+
      cdnGlobalRoutingHelper.CalculateRoutes ();
-   
+
 Default routes
 ^^^^^^^^^^^^^^
 
@@ -97,180 +97,16 @@
 
 ndnSIM comes with several different in-memory :ndnsim:`content store <ndn::ContentStore>` implementations, featuring different cache replacement policies.
 
-.. note:
-
-    The default content store uses LRU replacement policity and constrained with 100 cached ContentObjects.
-
 To select a particular content store and configure its capacity, use :ndnsim:`SetContentStore <ndn::StackHelper::SetContentStore>` helper method:
 
-- :ndnsim:`Least Recently Used (LRU) <ndn::cs::Lru>` (default):
-
       .. code-block:: c++
 
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Lru",
-                                    "MaxSize", "10000");
+         ndnHelper.SetContentStore ("<content store implementation>",
+                                    ["<optional parameter>", "<optional parameter's value>" [, ...]]);
 	 ...
 	 ndnHelper.Install (nodes);
 
-
-- :ndnsim:`First-In-First-Out (FIFO) <ndn::cs::Fifo>`:
-
-      .. code-block:: c++
-
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Fifo",
-                                    "MaxSize", "10000");
-	 ...
-	 ndnHelper.Install (nodes);
-
-- :ndnsim:`Random <ndn::cs::Random>`:
-
-      .. code-block:: c++
-
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Random",
-                                    "MaxSize", "10000");
-	 ...
-	 ndnHelper.Install (nodes);
-
-.. note::
-
-    If ``MaxSize`` parameter is omitted, then will be used a default value (100).
-
-.. note::
-
-    If ``MaxSize`` is set to 0, then no limit on ContentStore will be enforced 
-
-
-Content Store with entry lifetime tracking
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In order to evaluate lifetime of the content store entries, the special versions of the content store need to be used:
-
-- :ndnsim:`Least Recently Used (LRU) with cache entry lifetime tracking <ndn::cs::Stats::Lru>`:
-
-      .. code-block:: c++
-
-         void
-         CacheEntryRemoved (std::string context, Ptr<const ndn::cs::Entry> entry, Time lifetime)
-         {
-             std::cout << entry->GetName () << " " << lifetime.ToDouble (Time::S) << "s" << std::endl;
-         }
-
-         ...
-
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Stats::Lru",
-                                    "MaxSize", "10000");
-	 ...
-	 ndnHelper.Install (nodes);
-
-         // connect to lifetime trace
-         Config::Connect ("/NodeList/*/$ns3::ndn::cs::Stats::Lru/WillRemoveEntry", MakeCallback (CacheEntryRemoved));
-
-
-- :ndnsim:`First-In-First-Out (FIFO) with cache entry lifetime tracking <ndn::cs::Stats::Fifo>`:
-
-      .. code-block:: c++
-
-         void
-         CacheEntryRemoved (std::string context, Ptr<const ndn::cs::Entry> entry, Time lifetime)
-         {
-             std::cout << entry->GetName () << " " << lifetime.ToDouble (Time::S) << "s" << std::endl;
-         }
-
-         ...
-
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Stats::Fifo",
-                                    "MaxSize", "10000");
-	 ...
-	 ndnHelper.Install (nodes);
-
-         // connect to lifetime trace
-         Config::Connect ("/NodeList/*/$ns3::ndn::cs::Stats::Fifo/WillRemoveEntry", MakeCallback (CacheEntryRemoved));
-
-- :ndnsim:`Random with cache entry lifetime tracking <ndn::cs::Stats::Random>`:
-
-      .. code-block:: c++
-
-         void
-         CacheEntryRemoved (std::string context, Ptr<const ndn::cs::Entry> entry, Time lifetime)
-         {
-             std::cout << entry->GetName () << " " << lifetime.ToDouble (Time::S) << "s" << std::endl;
-         }
-
-         ...
-
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Stats::Random",
-                                    "MaxSize", "10000");
-	 ...
-	 ndnHelper.Install (nodes);
-
-         // connect to lifetime trace
-         Config::Connect ("/NodeList/*/$ns3::ndn::cs::Stats::Random/WillRemoveEntry", MakeCallback (CacheEntryRemoved));
-
-.. _Content Store respecting freshness field of ContentObjects:
-
-Content Store respecting freshness field of ContentObjects
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If simulations need Content Store which respects freshness of ContentObjects, the following versions of content store should be used:
-
-.. note:
-
-    Please note that currently, Freshness granularity is 1 second and maximum value is 65535 second. Value means infinity.
-
-- :ndnsim:`Least Recently Used (LRU) respecting ContentObject freshness <ndn::cs::Freshness::Lru>`:
-
-      .. code-block:: c++
-
-         ...
-
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Freshness::Lru",
-                                    "MaxSize", "10000");
-	 ...
-
-
-- :ndnsim:`First-In-First-Out (FIFO) respecting ContentObject freshness <ndn::cs::Freshness::Fifo>`:
-
-      .. code-block:: c++
-
-         ...
-
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Freshness::Fifo",
-                                    "MaxSize", "10000");
-	 ...
-
-- :ndnsim:`Random respecting ContentObject freshness <ndn::cs::Freshness::Random>`:
-
-      .. code-block:: c++
-
-         ...
-
-         ndnHelper.SetContentStore ("ns3::ndn::cs::Freshness::Random",
-                                    "MaxSize", "10000");
-	 ...
-
-The following example demonstrates a basic usage of a customized content store (``ndn-simple-with-content-freshness.cc``).  
-In this scenario two simple consumers (both installed on a consumer node) continually request the same data packet.  
-When Data producer specify unlimited freshness, Content keeps getting satisfied from local caches, while if freshness is specified, Interests periodically are getting through to the Data producer.
-
-.. aafig::
-    :aspect: 60
-    :scale: 120
-
-      +----------+                +--------+                +----------+
-      |          |     1Mbps      |        |      1Mbps     |          |
-      | Consumer |<-------------->| Router |<-------------->| Producer |
-      |          |         10ms   |        |         10ms   |          |
-      +----------+                +--------+                +----------+
-
-
-.. literalinclude:: ../../examples/ndn-simple-with-content-freshness.cc
-    :language: c++
-    :linenos:
-    :lines: 20-27,43-
-
-To run this scenario, use the following command::
-
-        NS_LOG=DumbRequester:ndn.cs.Freshness.Lru ./waf --run=ndn-simple-with-content-freshness
+In simulation scenarios it is possible to select one of :ref:`the existing implementations of the content store or implement your own <content store>`.
 
 
 Pending Interest Table
@@ -292,7 +128,7 @@
 	 ndnHelper.Install (nodes);
 
 - :ndnsim:`random <ndn::pit::Random>`:
-    
+
     when PIT reaches its limit, random entry (could be the newly created one) will be removed from PIT;
 
       .. code-block:: c++
@@ -318,43 +154,55 @@
 
 A desired :ndnsim:`forwarding strategy <ForwardingStrategy>` parameter need to be set before installing stack on a node.
 
-  Currently, there are following forwarding strategies that can be used in simulations:
-
-  - :ndnsim:`Flooding` (default)
-
-      Interests will be forwarded to all available faces available for a route (FIB entry).
-      If there are no available GREEN or YELLOW faces, interests is dropped.
+To select a particular forwarding strategy implementation and configure its parameters, use :ndnsim:`SetForwardingStrategy <ndn::StackHelper::SetContentStore>` helper method:
 
       .. code-block:: c++
 
-         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::Flooding");
-	 ...
-	 ndnHelper.Install (nodes);
-      
-
-  - :ndnsim:`SmartFlooding`
-
-      If GREEN face is available, Interest will be sent to the highest-ranked GREEN face. 
-      If not, Interest will be forwarded to all available faces available for a route (FIB entry)/
-      If there are no available GREEN or YELLOW faces, interests is dropped.
-
-      .. code-block:: c++
-
-         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::SmartFlooding");
+         ndnHelper.SetForwardingStrategy ("<forwarding strategy implementation>",
+                                          ["<optional parameter>", "<optional parameter's value>" [, ...]]);
 	 ...
 	 ndnHelper.Install (nodes);
 
-  - :ndnsim:`BestRoute`
+In simulation scenarios it is possible to select one of :ref:`the existing implementations of the forwarding strategy or implement your own <forwarding strategies>`.
 
-      If GREEN face is available, Interest will be sent to the highest-ranked GREEN face.
-      If not, Interest will be forwarded to the highest-ranked YELLOW face.
-      If there are no available GREEN or YELLOW faces, interests is dropped.
 
-      .. code-block:: c++
+.. Currently, there are following forwarding strategies that can be used in simulations:
 
-         ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute");
-	 ...
-	 ndnHelper.Install (nodes);
+..   - :ndnsim:`Flooding` (default)
+
+..       Interests will be forwarded to all available faces available for a route (FIB entry).
+..       If there are no available GREEN or YELLOW faces, interests is dropped.
+
+..       .. code-block:: c++
+
+..          ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::Flooding");
+.. 	 ...
+.. 	 ndnHelper.Install (nodes);
+
+
+..   - :ndnsim:`SmartFlooding`
+
+..       If GREEN face is available, Interest will be sent to the highest-ranked GREEN face.
+..       If not, Interest will be forwarded to all available faces available for a route (FIB entry)/
+..       If there are no available GREEN or YELLOW faces, interests is dropped.
+
+..       .. code-block:: c++
+
+..          ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::SmartFlooding");
+.. 	 ...
+.. 	 ndnHelper.Install (nodes);
+
+..   - :ndnsim:`BestRoute`
+
+..       If GREEN face is available, Interest will be sent to the highest-ranked GREEN face.
+..       If not, Interest will be forwarded to the highest-ranked YELLOW face.
+..       If there are no available GREEN or YELLOW faces, interests is dropped.
+
+..       .. code-block:: c++
+
+..          ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute");
+.. 	 ...
+.. 	 ndnHelper.Install (nodes);
 
 
 
@@ -394,3 +242,6 @@
       NodeContainer nodes;
       ...
       consumerHelper.Install (nodes)
+
+
+In simulation scenarios it is possible to select one of :ref:`the existing applications or implement your own <applications>`.
diff --git a/docs/source/index.rst b/docs/source/index.rst
index c2be159..0a564d6 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -3,7 +3,7 @@
 Welcome to ndnSIM NS-3 based NDN simulator
 ==========================================
 
-We invite you to `join our mailing list <http://www.lists.cs.ucla.edu/mailman/listinfo/ndnsim>`_ to see and participate in discussions about ndnSIM implementation and simulations in general (`mailing list archives <http://www.lists.cs.ucla.edu/pipermail/ndnsim/>`_). 
+We invite you to `join our mailing list <http://www.lists.cs.ucla.edu/mailman/listinfo/ndnsim>`_ to see and participate in discussions about ndnSIM implementation and simulations in general (`mailing list archives <http://www.lists.cs.ucla.edu/pipermail/ndnsim/>`_).
 
 
 Contents:
@@ -14,6 +14,7 @@
    intro
    getting-started
    helpers
+   cs
    fw
    applications
    examples