- status-notifier-cmd: the command line that is called when a host is down, or
   up. Accepted variables are:
     ${status} - down or up
-- link-up-interval: how long (in minutes) the pings don't have to fail
-  in order to consider the link up, or stable.
+- link-up-interval: how long (in minutes) the pings must be returned with
+  success in order to consider the link up, or stable.
+- link-down-interval: how long (in minutes) the pings must fail, in order to the
+  application consider the link down.
 
 
 2.2. Host
 
 
 - Documentation of the functions (doxygen)
 
-- Make the link down interval also configurable. Today it is possible just to
-  configure the amount of time the link must to be up to notify. Do another
-  configuration to allow the time of link down.
-
 - The interval between each ping to the same host is 1 second later than in the
   configuration file. For example, a ping configured to be performed each 5
   seconds takes 6.
 
     MaxPingFailLimit( 100 ),
     StatusNotifierCmd( "" ),
     LinkUpIntervalInMin( 0 ),
+    LinkDownIntervalInMin( 0 ),
     MinStableLinkIntervalInMin( 0 ),
     MaxStableLinkIntervalInMin( 60 ),
     Hosts()
     LinkUpIntervalInMin = link_up_interval_in_min;
 }
 
+int Configuration::get_link_down_interval_in_min() const
+{
+    return LinkDownIntervalInMin;
+}
+
+void Configuration::set_link_down_interval_in_min( const int link_down_interval_in_min )
+{
+    BOOST_ASSERT( ( MinStableLinkIntervalInMin <= link_down_interval_in_min ) && ( link_down_interval_in_min <= MaxStableLinkIntervalInMin ) );
+
+    LinkDownIntervalInMin = link_down_interval_in_min;
+}
+
 HostList Configuration::get_hosts() const
 {
     return Hosts;
 
     int get_link_up_interval_in_min() const;
     void set_link_up_interval_in_min( const int link_up_interval_in_min );
 
+    int get_link_down_interval_in_min() const;
+    void set_link_down_interval_in_min( const int link_down_interval_in_min );
+
     HostList get_hosts() const;
     void set_hosts( const HostList &hosts_list );
 
     int MaxPingFailLimit;
     std::string StatusNotifierCmd;
     int LinkUpIntervalInMin;
+    int LinkDownIntervalInMin;
     int MinStableLinkIntervalInMin;
     int MaxStableLinkIntervalInMin;
     HostList Hosts;
 
     DefaultLinkUpIntervalInMin( 5 ), // 5 minutes
     LinkUpIntervalCmdStr( "link-up-interval" ),
     LinkUpIntervalCmdDesc( "How long the link must be responsive in order to consider it stable." ),
+    DefaultLinkDownIntervalInMin( 2 ), // 2 minutes
+    LinkDownIntervalCmdStr( "link-down-interval" ),
+    LinkDownIntervalCmdDesc( "How long the link must be offline in order to consider it down." ),
     HostNameCmdStr( "host.name" ),
     HostNameCmdDesc( "Host address" ),
     DefaultHostIntervalInSec( 60 ), // 60 seconds
         ( PingFailLimitCmdStr.c_str(), value<int>()->default_value( DefaultPingFailLimit ), PingFailLimitCmdDesc.c_str() )
         ( StatusNotifierCmdCmdStr.c_str(), value<string>(), StatusNotifierCmdCmdDesc.c_str() )
         ( LinkUpIntervalCmdStr.c_str(), value<int>()->default_value( DefaultLinkUpIntervalInMin ), LinkUpIntervalCmdDesc.c_str() )
+        ( LinkDownIntervalCmdStr.c_str(), value<int>()->default_value( DefaultLinkDownIntervalInMin ), LinkDownIntervalCmdDesc.c_str() )
         ( HostNameCmdStr.c_str(), value< vector<string> >(), HostNameCmdDesc.c_str() )
         ( HostIntervalCmdStr.c_str(), value< vector<int> >(), HostIntervalCmdDesc.c_str() )
     ;
                 << link_up_interval_in_min << endl;
     }
 
+    // link-down-interval
+    if ( vm.count( LinkDownIntervalCmdStr ) > 0 )
+    {
+        int link_down_interval_in_min = vm[ LinkDownIntervalCmdStr ].as<int>();
+        Config.set_link_down_interval_in_min( link_down_interval_in_min );
+
+        GlobalLogger.info() << LinkDownIntervalCmdStr << "="
+                << link_down_interval_in_min << endl;
+    }
+
     // [host] name
     size_t hosts_names_count = 0;
     if ( vm.count( HostNameCmdStr ) > 0 )
 
     const int DefaultLinkUpIntervalInMin;
     const std::string LinkUpIntervalCmdStr;
     const std::string LinkUpIntervalCmdDesc;
+    const int DefaultLinkDownIntervalInMin;
+    const std::string LinkDownIntervalCmdStr;
+    const std::string LinkDownIntervalCmdDesc;
     const std::string HostNameCmdStr;
     const std::string HostNameCmdDesc;
     const int DefaultHostIntervalInSec;
 
 LinkStatusAnalyzer::LinkStatusAnalyzer(
         const int hosts_down_limit,
         const int link_up_interval_in_min,
+        const int link_down_interval_in_min,
         const string &status_notifier_cmd
 ) :
     HostsDownLimit( hosts_down_limit ),
     HostsDownList(),
     LinkUpIntervalInMin( link_up_interval_in_min ),
+    LinkDownIntervalInMin( link_down_interval_in_min ),
     CurrentLinkStatus( LinkStatus_Down ),
     CurrentNotificationStatus( NotificationStatus_NotReported ),
     TimeLinkStatusChanged( microsec_clock::universal_time() ),
 {
     BOOST_ASSERT( 0 <= hosts_down_limit );
     BOOST_ASSERT( 0 <= link_up_interval_in_min );
+    BOOST_ASSERT( 0 <= link_down_interval_in_min );
 }
 
 LinkStatusAnalyzer::~LinkStatusAnalyzer()
 {
     set_link_status( LinkStatus_Up );
 
-    // report the link status only if it is up longer than a configured amount
-    // of time and if we haven't reported the new status yet
+    // report the link status only if: it is up longer than a configured amount
+    // of time, and if we haven't reported the new status yet
     if ( is_link_up_enough_time() && can_report_link_status() )
     {
         BOOST_ASSERT( CurrentLinkStatus == LinkStatus_Up );
 {
     set_link_status( LinkStatus_Down );
 
-    if ( can_report_link_status() )
+    // report the link status only if: it is down longer than a configured amount
+    // of time, and if we haven't reported the new status yet
+    if ( is_link_down_enough_time() && can_report_link_status() )
     {
         BOOST_ASSERT( CurrentLinkStatus == LinkStatus_Down );
         BOOST_ASSERT( CurrentNotificationStatus == NotificationStatus_NotReported );
     return false;
 }
 
+bool LinkStatusAnalyzer::is_link_down_enough_time() const
+{
+    if ( CurrentLinkStatus == LinkStatus_Down )
+    {
+        ptime now = microsec_clock::universal_time();
+        long amount_time_link_is_down = (now - TimeLinkStatusChanged).total_seconds();
+        long link_down_interval_in_sec = LinkDownIntervalInMin * 60;
+
+        if ( amount_time_link_is_down >= link_down_interval_in_sec )
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 bool LinkStatusAnalyzer::can_report_link_status() const
 {
     return ( CurrentNotificationStatus == NotificationStatus_NotReported );
 
     LinkStatusAnalyzer(
             const int hosts_down_limit,
             const int link_up_interval_in_min,
+            const int link_down_interval_in_min,
             const std::string &status_notifier_cmd
     );
     ~LinkStatusAnalyzer();
     void notify_link_down();
 
     bool is_link_up_enough_time() const;
+    bool is_link_down_enough_time() const;
 
     bool can_report_link_status() const;
     void set_link_status(
     std::set<std::string> HostsDownList;
     /// interval the link have to be stable in order to consider it is functional
     const int LinkUpIntervalInMin;
+    /// interval the link have to be down in order to consider it is non-functional
+    const int LinkDownIntervalInMin;
     /// keep track of the actual link status
     LinkStatusAnalyzer::LinkStatus CurrentLinkStatus;
     /// indicates if the last link status change was notified
 
 {
     int hosts_down_limit = configuration->get_hosts_down_limit();
     int link_up_interval_in_min = configuration->get_link_up_interval_in_min();
+    int link_down_interval_in_min = configuration->get_link_down_interval_in_min();
     string status_notifier_cmd = configuration->get_status_notifier_cmd();
     LinkStatusAnalyzerItem link_analyzer(
             new LinkStatusAnalyzer(
                     hosts_down_limit,
                     link_up_interval_in_min,
+                    link_down_interval_in_min,
                     status_notifier_cmd
             )
     );