-cmake_minimum_required (VERSION 3.1)
+cmake_minimum_required (VERSION 3.12)
+
+project ( Stargazer )
 
 set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
 
 
 set ( CMAKE_POSITION_INDEPENDENT_CODE ON )
 
 if ( BUILD_LIB_COMMON )
+    find_package ( Iconv REQUIRED )
     add_library ( common STATIC common/blockio.cpp common/common.cpp common/strptime.cpp )
     target_include_directories ( common PUBLIC common/include )
+    target_link_libraries ( common Iconv::Iconv )
 endif ( BUILD_LIB_COMMON )
 
 if ( BUILD_LIB_CONFFILES )
 endif ( BUILD_LIB_IBPP )
 
 if ( BUILD_LIB_JSON )
+    find_package ( YAJL REQUIRED )
     add_library ( json STATIC json/generator.cpp json/parser.cpp )
     target_include_directories ( json PUBLIC json/include )
-    target_link_libraries ( json common )
+    target_link_libraries ( json common YAJL::YAJL )
 endif ( BUILD_LIB_JSON )
 
 if ( BUILD_LIB_LOGGER )
 
 
 set ( THREADS_PREFER_PTHREAD_FLAG ON )
 find_package ( Threads REQUIRED )
+find_package ( Intl REQUIRED )
 
 file ( READ sgauth.css CSS_DATA )
 configure_file ( css.h.in css.h ESCAPE_QUOTES @ONLY )
 
 set ( CMAKE_INCLUDE_CURRENT_DIR ON )
 
+include_directories ( ${Intl_INCLUDE_DIRS} )
+
 add_executable ( sgauth ${CPP_FILES} )
 
-target_link_libraries ( sgauth conffiles ia crypto common Threads::Threads )
+target_link_libraries ( sgauth conffiles ia crypto common ${Intl_LIBRARIES} Threads::Threads )
 
 # TODO: install
 
     std::cout << m_description << ":\n";
 std::for_each(m_options.begin(),
               m_options.end(),
-              std::bind2nd(std::mem_fun_ref(&OPTION::Help), level + 1));
+              [&level](const auto& opt){ opt.Help(level + 1); });
 }
 
 PARSER_STATE OPTION_BLOCK::Parse(int argc, char ** argv, void * data)
     return state;
 while (state.argc > 0 && !state.stop)
     {
-    std::vector<OPTION>::iterator it = std::find_if(m_options.begin(), m_options.end(), std::bind2nd(std::mem_fun_ref(&OPTION::Check), *state.argv));
+    const auto it = std::find_if(m_options.begin(), m_options.end(), [&state](const auto& opt){ return opt.Check(*state.argv); });
     if (it != m_options.end())
         state = it->Parse(--state.argc, ++state.argv, data);
     else
         break;
-    ++it;
     }
 return state;
 }
 
 std::for_each(
         parent::begin(),
         parent::end(),
-        std::mem_fun(&BASE_ACTION::Invoke)
-);
+        [](auto action){ action->Invoke(); });
 }
 
 #endif
 
     add_library ( mod_auth_ia MODULE authorization/inetaccess/inetaccess.cpp )
     target_link_libraries ( mod_auth_ia scriptexecuter crypto logger common )
     set_target_properties ( mod_auth_ia PROPERTIES PREFIX "" )
+    if ( ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" )
+        set_target_properties ( mod_auth_ia PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" )
+    endif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" )
 endif ( BUILD_MOD_IA )
 
 if ( BUILD_MOD_CAP_NF )
                                      configuration/sgconfig/parser_server_info.cpp )
     target_link_libraries ( mod_conf_sg scriptexecuter crypto logger common EXPAT::EXPAT )
     set_target_properties ( mod_conf_sg PROPERTIES PREFIX "" )
+    if ( ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" )
+        set_target_properties ( mod_conf_sg PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" )
+    endif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" )
 endif ( BUILD_MOD_SGCONFIG )
 
 if ( BUILD_MOD_RPCCONFIG )
     add_library ( mod_remote_script MODULE other/rscript/rscript.cpp other/rscript/nrmap_parser.cpp )
     target_link_libraries ( mod_remote_script crypto scriptexecuter logger common )
     set_target_properties ( mod_remote_script PROPERTIES PREFIX "" )
+    if ( ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" )
+        set_target_properties ( mod_remote_script PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" )
+    endif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" )
 endif ( BUILD_MOD_RSCRYPT )
 
 if ( BUILD_MOD_SMUX )
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-template <typename varType>
-class IS_CONTAINS_USER: public std::binary_function<varType, USER_PTR, bool>
-{
-public:
-    bool operator()(const varType& notifier, USER_PTR user) const
-        {
-        return notifier.GetUser() == user;
-        }
-};
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
 std::string AUTH_AO::GetVersion() const
 {
 return "Always Online authorizator v.1.0";
 users->AddNotifierUserAdd(&onAddUserNotifier);
 users->AddNotifierUserDel(&onDelUserNotifier);
 
-std::for_each(usersList.begin(), usersList.end(), std::bind1st(std::mem_fun(&AUTH_AO::UpdateUserAuthorization), this));
+std::for_each(usersList.begin(), usersList.end(), [this](auto user){ UpdateUserAuthorization(user); });
 
 isRunning = true;
 
 void AUTH_AO::UnSetUserNotifiers(USER_PTR u)
 {
 // ---      AlwaysOnline        ---
-IS_CONTAINS_USER<CHG_BEFORE_NOTIFIER<int> > IsContainsUserAOB;
-IS_CONTAINS_USER<CHG_AFTER_NOTIFIER<int> > IsContainsUserAOA;
-
 std::list<CHG_BEFORE_NOTIFIER<int> >::iterator aoBIter;
 std::list<CHG_AFTER_NOTIFIER<int> >::iterator  aoAIter;
 
 aoBIter = find_if(BeforeChgAONotifierList.begin(),
                   BeforeChgAONotifierList.end(),
-                  bind2nd(IsContainsUserAOB, u));
+                  [u](auto notifier){ return notifier.GetUser() == u; });
 
 if (aoBIter != BeforeChgAONotifierList.end())
     {
 
 aoAIter = find_if(AfterChgAONotifierList.begin(),
                   AfterChgAONotifierList.end(),
-                  bind2nd(IsContainsUserAOA, u));
+                  [u](auto notifier){ return notifier.GetUser() == u; });
 
 if (aoAIter != AfterChgAONotifierList.end())
     {
 // ---      AlwaysOnline end    ---
 
 // ---          IP              ---
-IS_CONTAINS_USER<CHG_BEFORE_NOTIFIER<USER_IPS> > IsContainsUserIPB;
-IS_CONTAINS_USER<CHG_AFTER_NOTIFIER<USER_IPS> >  IsContainsUserIPA;
-
 std::list<CHG_BEFORE_NOTIFIER<USER_IPS> >::iterator ipBIter;
 std::list<CHG_AFTER_NOTIFIER<USER_IPS> >::iterator  ipAIter;
 
 ipBIter = std::find_if(BeforeChgIPNotifierList.begin(),
                        BeforeChgIPNotifierList.end(),
-                       bind2nd(IsContainsUserIPB, u));
+                       [u](auto notifier){ return notifier.GetUser() == u; });
 
 if (ipBIter != BeforeChgIPNotifierList.end())
     {
 
 ipAIter = find_if(AfterChgIPNotifierList.begin(),
                   AfterChgIPNotifierList.end(),
-                  bind2nd(IsContainsUserIPA, u));
+                  [u](auto notifier){ return notifier.GetUser() == u; });
 
 if (ipAIter != AfterChgIPNotifierList.end())
     {
 
 #include <sys/types.h>
 #include <sys/socket.h>
 
+#ifndef MSG_NOSIGNAL
+// On OSX this flag does not exist.
+#define MSG_NOSIGNAL 0
+#endif
+
 using STG::Conn;
 using STG::Config;
 using STG::JSON::Parser;
 
 {
     STG_LOCKER lock(&mutex);
     std::vector<std::string> list;
-    std::transform(authorizedBy.begin(), authorizedBy.end(), std::back_inserter(list), std::mem_fun(&AUTH::GetVersion));
+    std::transform(authorizedBy.begin(), authorizedBy.end(), std::back_inserter(list), [](const auto auth){ return auth->GetVersion(); });
     return list;
 }
 //-----------------------------------------------------------------------------
 
     //printfd(__FILE__,"New Minute. old = %02d current = %02d\n", min, t->tm_min);
     //printfd(__FILE__,"New Day.    old = %2d current = %2d\n", day, t->tm_mday);
 
-    for_each(us->users.begin(), us->users.end(), std::mem_fun_ref(&USER_IMPL::Run));
+    for_each(us->users.begin(), us->users.end(), [](auto& user){ user.Run(); });
 
     tt = stgTime;
     localtime_r(&tt, &t);
 if (t.tm_hour == 23 && t.tm_min == 59)
     {
     printfd(__FILE__,"MidnightResetSessionStat\n");
-    for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::MidnightResetSessionStat));
+    for_each(users.begin(), users.end(), [](auto& user){ user.MidnightResetSessionStat(); });
     }
 
 if (TimeToWriteDetailStat(t))
         usr->WriteDetailStat();
         ++usr;
         if (usersCnt % 10 == 0)
-            for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::Run));
+            for_each(users.begin(), users.end(), [](auto& user){ user.Run(); });
         }
     }
 
 if (settings->GetSpreadFee())
     {
     printfd(__FILE__, "Spread DayFee\n");
-    for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDayFeeSpread));
+    for_each(users.begin(), users.end(), [](auto& user){ user.ProcessDayFeeSpread(); });
     }
 else
     {
     if (t.tm_mday == dayFee)
         {
         printfd(__FILE__, "DayFee\n");
-        for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDayFee));
+        for_each(users.begin(), users.end(), [](auto& user){ user.ProcessDayFee(); });
         }
     }
 
-std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDailyFee));
-std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessServices));
+std::for_each(users.begin(), users.end(), [](auto& user){ user.ProcessDailyFee(); });
+std::for_each(users.begin(), users.end(), [](auto& user){ user.ProcessServices(); });
 
 if (settings->GetDayFeeIsLastDay())
     {
 if (t1.tm_mday == dayResetTraff)
     {
     printfd(__FILE__, "ResetTraff\n");
-    for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessNewMonth));
+    for_each(users.begin(), users.end(), [](auto& user){ user.ProcessNewMonth(); });
     //for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::SetPrepaidTraff));
     }
 }
     }
 
 printfd(__FILE__, "Before USERS::Run()\n");
-for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::Run));
+for_each(users.begin(), users.end(), [](auto& user){ user.Run(); });
 
 // 'cause bind2st accepts only constant first param
 for (std::list<USER_IMPL>::iterator it = users.begin();
      ++it)
     it->WriteDetailStat(true);
 
-for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::WriteStat));
+for_each(users.begin(), users.end(), [](auto& user){ user.WriteStat(); });
 //for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::WriteConf));
 
 printfd(__FILE__, "USERS::Stop()\n");