text:
#include <strings.h>

#include <string>
#include <list>
#include <algorithm>
#include <memory>

#include "connection_handler/connection_handler_impl.h"
#include "transport_manager/info.h"
#include "encryption/hashing.h"

#ifdef ENABLE_SECURITY
#include "security_manager/security_manager.h"
#endif  // ENABLE_SECURITY

/**
 * \namespace connection_handler
 * \brief SmartDeviceLink ConnectionHandler namespace.
 */
namespace connection_handler {

CREATE_LOGGERPTR_GLOBAL(logger_, "ConnectionHandler")

ConnectionHandle HandleFromConnectionUID(transport_manager::ConnectionUID uid) {
  return ConnectionHandle(uid);
}

transport_manager::ConnectionUID ConnectionUIDFromHandle(
    ConnectionHandle handle) {
  return transport_manager::ConnectionUID(handle);
}

ConnectionHandlerImpl::ConnectionHandlerImpl(
    const ConnectionHandlerSettings& settings,
    transport_manager::TransportManager& tm)
    : settings_(settings)
    , connection_handler_observer_(NULL)
    , transport_manager_(tm)
    , protocol_handler_(NULL)
    , connection_list_lock_()
    , connection_handler_observer_lock_()
    , connection_list_deleter_(&connection_list_)
    , start_service_context_map_lock_()
    , start_service_context_map_() {}

ConnectionHandlerImpl::~ConnectionHandlerImpl() {
  LOG4CXX_AUTO_TRACE(logger_);
}

void ConnectionHandlerImpl::Stop() {
  LOG4CXX_AUTO_TRACE(logger_);
  ConnectionList::iterator itr = connection_list_.begin();
  while (itr != connection_list_.end()) {
    RemoveConnection(itr->second->connection_handle());
    itr = connection_list_.begin();
  }

  sync_primitives::AutoLock auto_lock(start_service_context_map_lock_);
  start_service_context_map_.clear();
}

void ConnectionHandlerImpl::set_connection_handler_observer(
    ConnectionHandlerObserver* observer) {
  LOG4CXX_DEBUG(logger_,
                "ConnectionHandlerImpl::set_connection_handler_observer() "
                    << observer);
  sync_primitives::AutoWriteLock write_lock(connection_handler_observer_lock_);
  if (!observer) {
    LOG4CXX_WARN(logger_, "Set Null pointer to observer.");
  }
  connection_handler_observer_ = observer;
}

void ConnectionHandlerImpl::set_protocol_handler(
    protocol_handler::ProtocolHandler* protocol_handler) {
  LOG4CXX_DEBUG(logger_,
                "ConnectionHandlerImpl::set_protocol_handler()"
                    << protocol_handler);
  if (!protocol_handler) {
    LOG4CXX_WARN(logger_, "Set Null pointer to protocol handler.");
  }
  protocol_handler_ = protocol_handler;
}

void ConnectionHandlerImpl::OnDeviceListUpdated(
    const std::vector<transport_manager::DeviceInfo>&) {
  LOG4CXX_AUTO_TRACE(logger_);
  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    connection_handler_observer_->OnDeviceListUpdated(device_list_);
  }
}

void ConnectionHandlerImpl::OnFindNewApplicationsRequest() {
  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    connection_handler_observer_->OnFindNewApplicationsRequest();
  }
}

void ConnectionHandlerImpl::OnDeviceFound(
    const transport_manager::DeviceInfo&) {
  LOG4CXX_AUTO_TRACE(logger_);
}

void ConnectionHandlerImpl::OnDeviceAdded(
    const transport_manager::DeviceInfo& device_info) {
  LOG4CXX_AUTO_TRACE(logger_);
  auto handle = device_info.device_handle();

  Device device(handle,
                device_info.name(),
                device_info.mac_address(),
                device_info.connection_type());

  auto result = device_list_.insert(std::make_pair(handle, device));

  if (!result.second) {
    LOG4CXX_ERROR(logger_,
                  "Device with handle " << handle
                                        << " is known already. "
                                           "Information won't be updated.");
    return;
  }
}

void ConnectionHandlerImpl::OnDeviceRemoved(
    const transport_manager::DeviceInfo& device_info) {
  LOG4CXX_AUTO_TRACE(logger_);
  // Device has been removed. Perform all needed actions.
  // 1. Delete all the connections and sessions of this device
  // 2. Delete device from a list
  // 3. Let observer know that device has been deleted.

  std::vector<ConnectionHandle> connections_to_remove;
  {
    sync_primitives::AutoReadLock lock(connection_list_lock_);
    for (ConnectionList::iterator it = connection_list_.begin();
         it != connection_list_.end();
         ++it) {
      if (device_info.device_handle() ==
          (*it).second->connection_device_handle()) {
        connections_to_remove.push_back((*it).first);
      }
    }
  }

  std::vector<ConnectionHandle>::iterator it = connections_to_remove.begin();
  for (; it != connections_to_remove.end(); ++it) {
    RemoveConnection(*it);
  }

  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    connection_handler_observer_->RemoveDevice(device_info.device_handle());
    connection_handler_observer_->OnDeviceListUpdated(device_list_);
  }
  device_list_.erase(device_info.device_handle());
}

void ConnectionHandlerImpl::OnDeviceSwitchingFinish(
    const transport_manager::DeviceUID& device_uid) {
  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    connection_handler_observer_->OnDeviceSwitchingFinish(
        encryption::MakeHash(device_uid));
  }
}

namespace {
struct DeviceFinder {
  explicit DeviceFinder(const std::string& device_uid)
      : device_uid_(device_uid) {}
  bool operator()(const DeviceMap::value_type& device) {
    return device_uid_ == device.second.mac_address();
  }

 private:
  const std::string& device_uid_;
};
}  // namespace

void ConnectionHandlerImpl::OnDeviceSwitchingStart(
    const std::string& device_uid_from, const std::string& device_uid_to) {
  auto device_from =
      std::find_if(device_list_.begin(),
                   device_list_.end(),
                   DeviceFinder(encryption::MakeHash(device_uid_from)));

  auto device_to =
      std::find_if(device_list_.begin(),
                   device_list_.end(),
                   DeviceFinder(encryption::MakeHash(device_uid_to)));

  DCHECK_OR_RETURN_VOID(device_list_.end() != device_from);
  DCHECK_OR_RETURN_VOID(device_list_.end() != device_to);
  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    connection_handler_observer_->OnDeviceSwitchingStart(device_from->second,
                                                         device_to->second);
  }
}

void ConnectionHandlerImpl::OnScanDevicesFinished() {
  LOG4CXX_AUTO_TRACE(logger_);
}

void ConnectionHandlerImpl::OnScanDevicesFailed(
    const transport_manager::SearchDeviceError& error) {
  LOG4CXX_WARN(logger_, "Scan devices failed. " << error.text());
}

void ConnectionHandlerImpl::OnConnectionEstablished(
    const transport_manager::DeviceInfo& device_info,
    const transport_manager::ConnectionUID connection_id) {
  LOG4CXX_AUTO_TRACE(logger_);

  DeviceMap::iterator it = device_list_.find(device_info.device_handle());
  if (device_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Unknown device!");
    return;
  }
  LOG4CXX_DEBUG(logger_,
                "Add Connection #" << connection_id << " to the list.");
  sync_primitives::AutoWriteLock lock(connection_list_lock_);
  connection_list_.insert(ConnectionList::value_type(
      connection_id,
      new Connection(connection_id,
                     device_info.device_handle(),
                     this,
                     get_settings().heart_beat_timeout())));
}

void ConnectionHandlerImpl::OnConnectionFailed(
    const transport_manager::DeviceInfo& device_info,
    const transport_manager::ConnectError& error) {
  // TODO(PV): implement
  LOG4CXX_ERROR(logger_, "Failed connecting.");
}

void ConnectionHandlerImpl::OnConnectionClosed(
    transport_manager::ConnectionUID connection_id) {
  LOG4CXX_AUTO_TRACE(logger_);

  OnConnectionEnded(connection_id);
}

void ConnectionHandlerImpl::OnConnectionClosedFailure(
    transport_manager::ConnectionUID connection_id,
    const transport_manager::DisconnectError& error) {
  // TODO(PV): implement
  LOG4CXX_ERROR(logger_, "ConnectionHandlerImpl::OnConnectionClosedFailure");
}

void ConnectionHandlerImpl::OnUnexpectedDisconnect(
    transport_manager::ConnectionUID connection_id,
    const transport_manager::CommunicationError& error) {
  LOG4CXX_AUTO_TRACE(logger_);

  OnConnectionEnded(connection_id);
}

void ConnectionHandlerImpl::OnDeviceConnectionLost(
    const transport_manager::DeviceHandle& device,
    const transport_manager::DisconnectDeviceError& error) {
  // TODO(PV): implement
  LOG4CXX_ERROR(logger_, "Lost connection with device " << device);
}

void ConnectionHandlerImpl::OnDisconnectFailed(
    const transport_manager::DeviceHandle& device,
    const transport_manager::DisconnectDeviceError& error) {
  // TODO(PV): implement
  LOG4CXX_ERROR(logger_, "Trying to Disconnect device failed.");
}

void ConnectionHandlerImpl::RemoveConnection(
    const ConnectionHandle connection_handle) {
  LOG4CXX_AUTO_TRACE(logger_);

  OnConnectionEnded(connection_handle);
}

#ifdef ENABLE_SECURITY
bool AllowProtection(const ConnectionHandlerSettings& settings,
                     const protocol_handler::ServiceType& service_type,
                     const bool is_protected) {
  const std::vector<int>& force_unprotected_list =
      is_protected ? settings.force_unprotected_service()
                   : settings.force_protected_service();

  if (std::find(force_unprotected_list.begin(),
                force_unprotected_list.end(),
                service_type) != force_unprotected_list.end()) {
    LOG4CXX_ERROR(logger_,
                  "Service " << static_cast<int>(service_type)
                             << " shall be protected");
    return false;
  }
  LOG4CXX_DEBUG(logger_,
                "Service " << static_cast<int>(service_type) << " allowed");
  return true;
}
#endif  // ENABLE_SECURITY

uint32_t ConnectionHandlerImpl::OnSessionStartedCallback(
    const transport_manager::ConnectionUID connection_handle,
    const uint8_t session_id,
    const protocol_handler::ServiceType& service_type,
    const bool is_protected,
    uint32_t* hash_id) {
  LOG4CXX_AUTO_TRACE(logger_);

  if (hash_id) {
    *hash_id = protocol_handler::HASH_ID_WRONG;
  }

#ifdef ENABLE_SECURITY
  if (!AllowProtection(get_settings(), service_type, is_protected)) {
    return 0;
  }
#endif  // ENABLE_SECURITY
  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Unknown connection!");
    return 0;
  }
  uint32_t new_session_id = 0;

  Connection* connection = it->second;
  if ((0 == session_id) && (protocol_handler::kRpc == service_type)) {
    new_session_id = connection->AddNewSession();
    if (0 == new_session_id) {
      LOG4CXX_ERROR(logger_, "Couldn't start new session!");
      return 0;
    }
    if (hash_id) {
      *hash_id = KeyFromPair(connection_handle, new_session_id);
    }
  } else {  // Could be create new service or protected exists one
    if (!connection->AddNewService(session_id, service_type, is_protected)) {
      LOG4CXX_ERROR(logger_,
                    "Couldn't establish "
#ifdef ENABLE_SECURITY
                        << (is_protected ? "protected" : "non-protected")
#endif  // ENABLE_SECURITY
                        << " service " << static_cast<int>(service_type)
                        << " for session " << static_cast<int>(session_id));
      return 0;
    }
    new_session_id = session_id;
    if (hash_id) {
      *hash_id = protocol_handler::HASH_ID_NOT_SUPPORTED;
    }
  }
  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    const uint32_t session_key = KeyFromPair(connection_handle, new_session_id);
    const bool success = connection_handler_observer_->OnServiceStartedCallback(
        connection->connection_device_handle(), session_key, service_type);
    if (!success) {
      LOG4CXX_WARN(logger_,
                   "Service starting forbidden by connection_handler_observer");
      if (protocol_handler::kRpc == service_type) {
        connection->RemoveSession(new_session_id);
      } else {
        connection->RemoveService(session_id, service_type);
      }
      return 0;
    }
  }
  return new_session_id;
}

void ConnectionHandlerImpl::OnSessionStartedCallback(
    const transport_manager::ConnectionUID connection_handle,
    const uint8_t session_id,
    const protocol_handler::ServiceType& service_type,
    const bool is_protected,
    const BsonObject* params) {
  LOG4CXX_AUTO_TRACE(logger_);

  std::vector<std::string> rejected_params;
  protocol_handler::SessionContext context(connection_handle,
                                           session_id,
                                           0,
                                           service_type,
                                           protocol_handler::HASH_ID_WRONG,
                                           is_protected);

#ifdef ENABLE_SECURITY
  if (!AllowProtection(get_settings(), service_type, is_protected)) {
    protocol_handler_->NotifySessionStarted(context, rejected_params);
    return;
  }
#endif  // ENABLE_SECURITY
  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Unknown connection!");
    protocol_handler_->NotifySessionStarted(context, rejected_params);
    return;
  }

  Connection* connection = it->second;
  context.is_new_service_ =
      !connection->SessionServiceExists(session_id, service_type);

  if ((0 == session_id) && (protocol_handler::kRpc == service_type)) {
    context.new_session_id_ = connection->AddNewSession();
    if (0 == context.new_session_id_) {
      LOG4CXX_ERROR(logger_, "Couldn't start new session!");
      protocol_handler_->NotifySessionStarted(context, rejected_params);
      return;
    }
    context.hash_id_ = KeyFromPair(connection_handle, context.new_session_id_);
  } else {  // Could be create new service or protected exists one
    if (!connection->AddNewService(session_id, service_type, is_protected)) {
      LOG4CXX_ERROR(logger_,
                    "Couldn't establish "
#ifdef ENABLE_SECURITY
                        << (is_protected ? "protected" : "non-protected")
#endif  // ENABLE_SECURITY
                        << " service " << static_cast<int>(service_type)
                        << " for session " << static_cast<int>(session_id));
      protocol_handler_->NotifySessionStarted(context, rejected_params);
      return;
    }
    context.new_session_id_ = session_id;
    context.hash_id_ = protocol_handler::HASH_ID_NOT_SUPPORTED;
  }
  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    const uint32_t session_key =
        KeyFromPair(connection_handle, context.new_session_id_);

    uint32_t app_id = 0;
    GetDataOnSessionKey(
        session_key, &app_id, NULL, static_cast<DeviceHandle*>(NULL));
    if (app_id > 0) {
      context.is_ptu_required_ =
          !connection_handler_observer_->CheckAppIsNavi(app_id);
    }

    {
      sync_primitives::AutoLock auto_lock(start_service_context_map_lock_);
      start_service_context_map_[session_key] = context;
    }

    connection_handler_observer_->OnServiceStartedCallback(
        connection->connection_device_handle(),
        session_key,
        service_type,
        params);
  } else {
    if (protocol_handler_) {
      protocol_handler_->NotifySessionStarted(context, rejected_params);
    }
  }
}

void ConnectionHandlerImpl::NotifyServiceStartedResult(
    uint32_t session_key,
    bool result,
    std::vector<std::string>& rejected_params) {
  LOG4CXX_AUTO_TRACE(logger_);

  protocol_handler::SessionContext context;
  {
    sync_primitives::AutoLock auto_lock(start_service_context_map_lock_);
    auto it = start_service_context_map_.find(session_key);
    if (it == start_service_context_map_.end()) {
      LOG4CXX_ERROR(logger_, "context for start service not found!");
      return;
    }
    context = it->second;
    start_service_context_map_.erase(it);
  }

  Connection* connection = NULL;
  {
    sync_primitives::AutoReadLock lock(connection_list_lock_);
    ConnectionList::iterator it = connection_list_.find(context.connection_id_);
    if (connection_list_.end() == it) {
      LOG4CXX_ERROR(logger_, "connection not found");
      return;
    }
    connection = it->second;
  }

  if (!result) {
    LOG4CXX_WARN(logger_,
                 "Service starting forbidden by connection_handler_observer");
    if (protocol_handler::kRpc == context.service_type_) {
      connection->RemoveSession(context.new_session_id_);
    } else {
      connection->RemoveService(context.initial_session_id_,
                                context.service_type_);
    }
    context.new_session_id_ = 0;
  }

  if (protocol_handler_ != NULL) {
    protocol_handler_->NotifySessionStarted(context, rejected_params);
  }
}

void ConnectionHandlerImpl::OnApplicationFloodCallBack(
    const uint32_t& connection_key) {
  LOG4CXX_AUTO_TRACE(logger_);

  transport_manager::ConnectionUID connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(connection_key, &connection_handle, &session_id);

  LOG4CXX_INFO(logger_, "Disconnect flooding application");
  if (session_id != 0) {
    CloseSession(connection_handle, session_id, kFlood);
  } else {
    CloseConnectionSessions(connection_handle, kCommon);
    CloseConnection(connection_handle);
  }
}

void ConnectionHandlerImpl::OnMalformedMessageCallback(
    const uint32_t& connection_key) {
  LOG4CXX_AUTO_TRACE(logger_);

  transport_manager::ConnectionUID connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(connection_key, &connection_handle, &session_id);

  LOG4CXX_INFO(logger_, "Disconnect malformed messaging application");
  CloseConnectionSessions(connection_handle, kMalformed);
  CloseConnection(connection_handle);
}

uint32_t ConnectionHandlerImpl::OnSessionEndedCallback(
    const transport_manager::ConnectionUID connection_handle,
    const uint8_t session_id,
    const uint32_t& hashCode,
    const protocol_handler::ServiceType& service_type) {
  uint32_t hashValue = hashCode;
  return OnSessionEndedCallback(
      connection_handle, session_id, &hashValue, service_type);
}

uint32_t ConnectionHandlerImpl::OnSessionEndedCallback(
    const transport_manager::ConnectionUID connection_handle,
    const uint8_t session_id,
    uint32_t* hashCode,
    const protocol_handler::ServiceType& service_type) {
  LOG4CXX_AUTO_TRACE(logger_);

  connection_list_lock_.AcquireForReading();
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() == it) {
    LOG4CXX_WARN(logger_, "Unknown connection!");
    connection_list_lock_.Release();
    return 0;
  }
  std::pair<int32_t, Connection*> connection_item = *it;
  connection_list_lock_.Release();

  Connection* connection = connection_item.second;
  const uint32_t session_key = KeyFromPair(connection_handle, session_id);

  if (protocol_handler::kRpc == service_type) {
    LOG4CXX_INFO(logger_,
                 "Session " << static_cast<uint32_t>(session_id)
                            << " to be removed");
    // old version of protocol doesn't support hash
    if (protocol_handler::HASH_ID_NOT_SUPPORTED != *hashCode) {
      if (protocol_handler::HASH_ID_WRONG == *hashCode ||
          session_key != *hashCode) {
        LOG4CXX_WARN(logger_,
                     "Wrong hash_id for session "
                         << static_cast<uint32_t>(session_id));
        *hashCode = protocol_handler::HASH_ID_WRONG;
        return 0;
      }
    }
    if (!connection->RemoveSession(session_id)) {
      LOG4CXX_WARN(logger_,
                   "Couldn't remove session "
                       << static_cast<uint32_t>(session_id));
      return 0;
    }
  } else {
    LOG4CXX_INFO(logger_,
                 "Service " << static_cast<uint32_t>(service_type)
                            << " to be removed");
    if (!connection->RemoveService(session_id, service_type)) {
      LOG4CXX_WARN(logger_,
                   "Couldn't remove service "
                       << static_cast<uint32_t>(service_type));
      return 0;
    }
  }

  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    connection_handler_observer_->OnServiceEndedCallback(
        session_key, service_type, CloseSessionReason::kCommon);
  }
  return session_key;
}

uint32_t ConnectionHandlerImpl::KeyFromPair(
    transport_manager::ConnectionUID connection_handle,
    uint8_t session_id) const {
  const uint32_t key = connection_handle | (session_id << 16);
  LOG4CXX_DEBUG(logger_,
                "Key for ConnectionHandle:"
                    << static_cast<uint32_t>(connection_handle)
                    << " Session:" << static_cast<uint32_t>(session_id)
                    << " is: " << static_cast<uint32_t>(key));
  if (protocol_handler::HASH_ID_WRONG == key) {
    LOG4CXX_ERROR(logger_,
                  "Connection key is WRONG_HASH_ID "
                  "(session id shall be greater 0)");
  }
  return key;
}

void ConnectionHandlerImpl::PairFromKey(
    uint32_t key,
    transport_manager::ConnectionUID* connection_handle,
    uint8_t* session_id) const {
  *connection_handle = key & 0xFF00FFFF;
  *session_id = key >> 16;
  LOG4CXX_DEBUG(
      logger_,
      "ConnectionHandle:" << static_cast<int32_t>(*connection_handle)
                          << " Session:" << static_cast<int32_t>(*session_id)
                          << " for key:" << static_cast<int32_t>(key));
}

int32_t ConnectionHandlerImpl::GetDataOnSessionKey(
    uint32_t key,
    uint32_t* app_id,
    std::list<int32_t>* sessions_list,
    connection_handler::DeviceHandle* device_id) const {
  LOG4CXX_AUTO_TRACE(logger_);

  const int32_t error_result = -1;
  transport_manager::ConnectionUID conn_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(key, &conn_handle, &session_id);

  ConnectionList::const_iterator it = connection_list_.find(conn_handle);
  if (connection_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Connection not found for key: " << key);
    return error_result;
  }

  const Connection& connection = *it->second;
  const SessionMap session_map = connection.session_map();
  if (0 == session_id || session_map.end() == session_map.find(session_id)) {
    LOG4CXX_ERROR(logger_,
                  "Session not found in connection: "
                      << static_cast<int32_t>(conn_handle));
    return error_result;
  }

  if (device_id) {
    *device_id = connection.connection_device_handle();
  }
  if (app_id) {
    *app_id = KeyFromPair(conn_handle, session_id);
  }
  if (sessions_list) {
    sessions_list->clear();

    SessionMap::const_iterator session_it = session_map.begin();
    for (; session_map.end() != session_it; ++session_it) {
      sessions_list->push_back(KeyFromPair(conn_handle, it->first));
    }
  }

  LOG4CXX_INFO(logger_,
               "Connection " << static_cast<int32_t>(conn_handle) << " has "
                             << session_map.size() << " sessions.");
  return 0;
}

int32_t ConnectionHandlerImpl::GetDataOnSessionKey(
    uint32_t key,
    uint32_t* app_id,
    std::list<int32_t>* sessions_list,
    uint32_t* device_id) const {
  LOG4CXX_AUTO_TRACE(logger_);
  DeviceHandle handle;
  int32_t result = GetDataOnSessionKey(key, app_id, sessions_list, &handle);
  *device_id = static_cast<uint32_t>(handle);
  return result;
}

const ConnectionHandlerSettings& ConnectionHandlerImpl::get_settings() const {
  return settings_;
}

const protocol_handler::SessionObserver&
ConnectionHandlerImpl::get_session_observer() {
  return *this;
}

DevicesDiscoveryStarter& ConnectionHandlerImpl::get_device_discovery_starter() {
  return *this;
}

struct CompareMAC {
  explicit CompareMAC(const std::string& mac) : mac_(mac) {}
  bool operator()(const DeviceMap::value_type& device) {
    return strcasecmp(device.second.mac_address().c_str(), mac_.c_str()) == 0;
  }

 private:
  std::string mac_;
};

bool ConnectionHandlerImpl::GetDeviceID(const std::string& mac_address,
                                        DeviceHandle* device_handle) {
  DCHECK_OR_RETURN(device_handle, false);
  DeviceMap::const_iterator it = std::find_if(
      device_list_.begin(), device_list_.end(), CompareMAC(mac_address));
  if (it != device_list_.end()) {
    *device_handle = it->first;
    return true;
  }
  return false;
}

int32_t ConnectionHandlerImpl::GetDataOnDeviceID(
    DeviceHandle device_handle,
    std::string* device_name,
    std::list<uint32_t>* applications_list,
    std::string* mac_address,
    std::string* connection_type) const {
  LOG4CXX_AUTO_TRACE(logger_);

  int32_t result = -1;
  DeviceMap::const_iterator it = device_list_.find(device_handle);
  if (device_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Device not found for handle " << device_handle);
    return result;
  }

  if (device_name) {
    *device_name = it->second.user_friendly_name();
  }
  if (connection_type) {
    *connection_type = it->second.connection_type();
  }
  if (applications_list) {
    applications_list->clear();
    sync_primitives::AutoReadLock connection_list_lock(connection_list_lock_);
    for (ConnectionList::const_iterator itr = connection_list_.begin();
         itr != connection_list_.end();
         ++itr) {
      if (device_handle == (*itr).second->connection_device_handle()) {
        const SessionMap& session_map = (itr->second)->session_map();
        for (SessionMap::const_iterator session_it = session_map.begin();
             session_map.end() != session_it;
             ++session_it) {
          const transport_manager::ConnectionUID connection_handle = itr->first;
          const uint32_t session_id = session_it->first;
          const uint32_t application_id =
              KeyFromPair(connection_handle, session_id);
          applications_list->push_back(application_id);
        }
      }
    }
  }

  if (mac_address) {
    *mac_address = it->second.mac_address();
  }

  result = 0;

  return result;
}

void ConnectionHandlerImpl::GetConnectedDevicesMAC(
    std::vector<std::string>& device_macs) const {
  DeviceMap::const_iterator first = device_list_.begin();
  DeviceMap::const_iterator last = device_list_.end();

  while (first != last) {
    device_macs.push_back((*first).second.mac_address());
    ++first;
  }
}

#ifdef ENABLE_SECURITY
int ConnectionHandlerImpl::SetSSLContext(
    const uint32_t& key, security_manager::SSLContext* context) {
  LOG4CXX_AUTO_TRACE(logger_);
  transport_manager::ConnectionUID connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(key, &connection_handle, &session_id);

  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Unknown connection!");
    return security_manager::SecurityManager::ERROR_INTERNAL;
  }
  Connection& connection = *it->second;
  return connection.SetSSLContext(session_id, context);
}

security_manager::SSLContext* ConnectionHandlerImpl::GetSSLContext(
    const uint32_t& key, const protocol_handler::ServiceType& service_type) {
  LOG4CXX_AUTO_TRACE(logger_);
  transport_manager::ConnectionUID connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(key, &connection_handle, &session_id);

  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Unknown connection!");
    return NULL;
  }
  Connection& connection = *it->second;
  return connection.GetSSLContext(session_id, service_type);
}

void ConnectionHandlerImpl::SetProtectionFlag(
    const uint32_t& key, const protocol_handler::ServiceType& service_type) {
  LOG4CXX_AUTO_TRACE(logger_);
  transport_manager::ConnectionUID connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(key, &connection_handle, &session_id);

  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Unknown connection!");
    return;
  }
  Connection& connection = *it->second;
  connection.SetProtectionFlag(session_id, service_type);
}

security_manager::SSLContext::HandshakeContext
ConnectionHandlerImpl::GetHandshakeContext(uint32_t key) const {
  return connection_handler_observer_->GetHandshakeContext(key);
}

#endif  // ENABLE_SECURITY

bool ConnectionHandlerImpl::SessionServiceExists(
    const uint32_t connection_key,
    const protocol_handler::ServiceType& service_type) const {
  LOG4CXX_AUTO_TRACE(logger_);
  transport_manager::ConnectionUID connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(connection_key, &connection_handle, &session_id);

  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::const_iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() == it) {
    LOG4CXX_ERROR(logger_, "Unknown connection!");
    return false;
  }
  const Connection& connection = *it->second;
  return connection.SessionServiceExists(session_id, service_type);
}

void ConnectionHandlerImpl::StartDevicesDiscovery() {
  LOG4CXX_AUTO_TRACE(logger_);

  transport_manager_.SearchDevices();
  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_) {
    connection_handler_observer_->OnDeviceListUpdated(device_list_);
  }
}

void ConnectionHandlerImpl::ConnectToDevice(
    connection_handler::DeviceHandle device_handle) {
  connection_handler::DeviceMap::const_iterator it_in;
  it_in = device_list_.find(device_handle);
  if (device_list_.end() != it_in) {
    LOG4CXX_INFO(logger_, "Connecting to device with handle " << device_handle);
    if (transport_manager::E_SUCCESS !=
        transport_manager_.ConnectDevice(device_handle)) {
      LOG4CXX_WARN(logger_, "Can't connect to device");
    } else {
      LOG4CXX_ERROR(
          logger_,
          "Application Manager wanted to connect to non-existing device");
    }
  }
}

void ConnectionHandlerImpl::RunAppOnDevice(const std::string& device_mac,
                                           const std::string& bundle_id) const {
  for (DeviceMap::const_iterator i = device_list_.begin();
       i != device_list_.end();
       ++i) {
    const connection_handler::Device& device = i->second;
    if (device.mac_address() == device_mac) {
      transport_manager_.RunAppOnDevice(device.device_handle(), bundle_id);
      return;
    }
  }
  LOG4CXX_WARN(logger_, "No apps found on device " << device_mac);
}

void ConnectionHandlerImpl::ConnectToAllDevices() {
  for (DeviceMap::iterator i = device_list_.begin(); i != device_list_.end();
       ++i) {
    connection_handler::DeviceHandle device_handle = i->first;
    ConnectToDevice(device_handle);
  }
}

void ConnectionHandlerImpl::StartTransportManager() {
  LOG4CXX_AUTO_TRACE(logger_);
  transport_manager_.Visibility(true);
}

void ConnectionHandlerImpl::CloseRevokedConnection(uint32_t connection_key) {
  LOG4CXX_AUTO_TRACE(logger_);

  uint32_t connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(connection_key, &connection_handle, &session_id);

  CloseConnection(connection_handle);
}

void ConnectionHandlerImpl::CloseConnection(
    ConnectionHandle connection_handle) {
  LOG4CXX_AUTO_TRACE(logger_);
  transport_manager::ConnectionUID connection_uid =
      ConnectionUIDFromHandle(connection_handle);
  transport_manager_.DisconnectForce(connection_uid);

  sync_primitives::AutoWriteLock connection_list_lock(connection_list_lock_);

  ConnectionList::iterator connection_list_itr =
      connection_list_.find(connection_uid);
  if (connection_list_.end() != connection_list_itr) {
    connection_list_.erase(connection_list_itr);
  }
}

uint32_t ConnectionHandlerImpl::GetConnectionSessionsCount(
    uint32_t connection_key) {
  LOG4CXX_AUTO_TRACE(logger_);
  uint32_t connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(connection_key, &connection_handle, &session_id);

  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator itr = connection_list_.find(connection_handle);

  if (connection_list_.end() != itr) {
    return itr->second->session_map().size();
  }

  return 0;
}

void ConnectionHandlerImpl::CloseSession(uint32_t key,
                                         CloseSessionReason close_reason) {
  uint32_t connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(key, &connection_handle, &session_id);

  CloseSession(connection_handle, session_id, close_reason);
}

void ConnectionHandlerImpl::CloseSession(ConnectionHandle connection_handle,
                                         uint8_t session_id,
                                         CloseSessionReason close_reason) {
  LOG4CXX_AUTO_TRACE(logger_);
  LOG4CXX_DEBUG(logger_,
                "Closing session with id: " << static_cast<int>(session_id));

  // In case of malformed message the connection should be broke up without
  // any other notification to mobile.
  if (close_reason != kMalformed && protocol_handler_) {
    protocol_handler_->SendEndSession(connection_handle, session_id);
  }

  transport_manager::ConnectionUID connection_id =
      ConnectionUIDFromHandle(connection_handle);

  SessionMap session_map;
  {
    sync_primitives::AutoReadLock connection_list_lock(connection_list_lock_);

    ConnectionList::iterator connection_list_itr =
        connection_list_.find(connection_id);
    if (connection_list_.end() != connection_list_itr) {
      session_map = connection_list_itr->second->session_map();
      connection_list_itr->second->RemoveSession(session_id);
    } else {
      LOG4CXX_ERROR(logger_,
                    "Connection with id: " << connection_id << " not found");
      return;
    }
  }

  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (!connection_handler_observer_) {
    LOG4CXX_ERROR(logger_, "Connection handler observer not found");
    return;
  }

  SessionMap::const_iterator session_map_itr = session_map.find(session_id);
  if (session_map_itr != session_map.end()) {
    const uint32_t session_key = KeyFromPair(connection_id, session_id);
    const Session& session = session_map_itr->second;
    const ServiceList& service_list = session.service_list;

    ServiceList::const_reverse_iterator service_list_itr =
        service_list.rbegin();
    for (; service_list_itr != service_list.rend(); ++service_list_itr) {
      const protocol_handler::ServiceType service_type =
          service_list_itr->service_type;
      connection_handler_observer_->OnServiceEndedCallback(
          session_key, service_type, close_reason);
    }
  } else {
    LOG4CXX_ERROR(logger_, "Session with id: " << session_id << " not found");
    return;
  }

  LOG4CXX_DEBUG(logger_,
                "Session with id: " << session_id
                                    << " has been closed successfully");
}

void ConnectionHandlerImpl::CloseConnectionSessions(
    ConnectionHandle connection_handle, CloseSessionReason close_reason) {
  LOG4CXX_AUTO_TRACE(logger_);

  transport_manager::ConnectionUID connection_id =
      ConnectionUIDFromHandle(connection_handle);

  LOG4CXX_DEBUG(
      logger_,
      "Closing all sessions for connection with id: " << connection_id);

  typedef std::vector<uint8_t> SessionIdVector;
  SessionIdVector session_id_vector;
  {
    sync_primitives::AutoReadLock connection_list_lock(connection_list_lock_);

    ConnectionList::iterator connection_list_itr =
        connection_list_.find(connection_id);
    if (connection_list_.end() != connection_list_itr) {
      const SessionMap session_map = connection_list_itr->second->session_map();

      SessionMap::const_iterator session_map_itr = session_map.begin();
      for (; session_map_itr != session_map.end(); ++session_map_itr) {
        session_id_vector.push_back(session_map_itr->first);
      }
    } else {
      LOG4CXX_ERROR(logger_,
                    "Connection with id: " << connection_id << " not found");
      return;
    }
  }
  SessionIdVector::const_iterator session_id_itr = session_id_vector.begin();
  for (; session_id_itr != session_id_vector.end(); ++session_id_itr) {
    CloseSession(connection_handle, *session_id_itr, close_reason);
  }
  session_id_vector.clear();

  LOG4CXX_DEBUG(logger_,
                "All sessions for connection with id: "
                    << connection_id << " have been closed successfully");
}

void ConnectionHandlerImpl::SendEndService(uint32_t key, uint8_t service_type) {
  if (protocol_handler_) {
    uint32_t connection_handle = 0;
    uint8_t session_id = 0;
    PairFromKey(key, &connection_handle, &session_id);
    protocol_handler_->SendEndService(
        connection_handle, session_id, service_type);
  }
}

void ConnectionHandlerImpl::StartSessionHeartBeat(uint32_t connection_key) {
  LOG4CXX_AUTO_TRACE(logger_);
  uint32_t connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(connection_key, &connection_handle, &session_id);

  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() != it) {
    it->second->StartHeartBeat(session_id);
  }
}

void ConnectionHandlerImpl::SetHeartBeatTimeout(uint32_t connection_key,
                                                uint32_t timeout) {
  LOG4CXX_AUTO_TRACE(logger_);
  uint32_t connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(connection_key, &connection_handle, &session_id);
  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() != it) {
    it->second->SetHeartBeatTimeout(timeout, session_id);
  }
}

void ConnectionHandlerImpl::SendHeartBeat(ConnectionHandle connection_handle,
                                          uint8_t session_id) {
  transport_manager::ConnectionUID connection_uid =
      ConnectionUIDFromHandle(connection_handle);
  if (protocol_handler_) {
    protocol_handler_->SendHeartBeat(connection_uid, session_id);
  }
}

void ConnectionHandlerImpl::KeepConnectionAlive(uint32_t connection_key,
                                                uint8_t session_id) {
  LOG4CXX_AUTO_TRACE(logger_);
  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_key);
  if (connection_list_.end() != it) {
    it->second->KeepAlive(session_id);
  }
}

void ConnectionHandlerImpl::OnConnectionEnded(
    const transport_manager::ConnectionUID connection_id) {
  LOG4CXX_INFO(logger_,
               "Delete Connection: " << static_cast<int32_t>(connection_id)
                                     << " from the list.");
  connection_list_lock_.AcquireForWriting();
  ConnectionList::iterator itr = connection_list_.find(connection_id);
  if (connection_list_.end() == itr) {
    LOG4CXX_ERROR(logger_, "Connection not found!");
    connection_list_lock_.Release();
    return;
  }
  std::auto_ptr<Connection> connection(itr->second);
  connection_list_.erase(itr);
  connection_list_lock_.Release();

  sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
  if (connection_handler_observer_ && connection.get() != NULL) {
    const SessionMap session_map = connection->session_map();

    for (SessionMap::const_iterator session_it = session_map.begin();
         session_map.end() != session_it;
         ++session_it) {
      const uint32_t session_key =
          KeyFromPair(connection_id, session_it->first);
      const ServiceList& service_list = session_it->second.service_list;
      for (ServiceList::const_iterator service_it = service_list.begin(),
                                       end = service_list.end();
           service_it != end;
           ++service_it) {
        connection_handler_observer_->OnServiceEndedCallback(
            session_key, service_it->service_type, CloseSessionReason::kCommon);
      }
    }
  }
}

void ConnectionHandlerImpl::BindProtocolVersionWithSession(
    uint32_t connection_key, uint8_t protocol_version) {
  LOG4CXX_AUTO_TRACE(logger_);
  uint32_t connection_handle = 0;
  uint8_t session_id = 0;
  PairFromKey(connection_key, &connection_handle, &session_id);

  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::iterator it = connection_list_.find(connection_handle);
  if (connection_list_.end() != it) {
    it->second->UpdateProtocolVersionSession(session_id, protocol_version);
  }
}

bool ConnectionHandlerImpl::IsHeartBeatSupported(
    transport_manager::ConnectionUID connection_handle,
    uint8_t session_id) const {
  LOG4CXX_AUTO_TRACE(logger_);
  sync_primitives::AutoReadLock lock(connection_list_lock_);
  uint32_t connection = static_cast<uint32_t>(connection_handle);
  ConnectionList::const_iterator it = connection_list_.find(connection);
  if (connection_list_.end() == it) {
    LOG4CXX_WARN(logger_, "Connection not found !");
    return false;
  }
  return it->second->SupportHeartBeat(session_id);
}

bool ConnectionHandlerImpl::ProtocolVersionUsed(
    uint32_t connection_id,
    uint8_t session_id,
    uint8_t& protocol_version) const {
  LOG4CXX_AUTO_TRACE(logger_);
  sync_primitives::AutoReadLock lock(connection_list_lock_);
  ConnectionList::const_iterator it = connection_list_.find(connection_id);
  if (connection_list_.end() != it) {
    return it->second->ProtocolVersion(session_id, protocol_version);
  }
  LOG4CXX_WARN(logger_, "Connection not found !");
  return false;
}

#ifdef BUILD_TESTS
ConnectionList& ConnectionHandlerImpl::getConnectionList() {
  return connection_list_;
}

const DeviceMap& ConnectionHandlerImpl::getDeviceList() {
  return device_list_;
}

void ConnectionHandlerImpl::addDeviceConnection(
    const transport_manager::DeviceInfo& device_info,
    const transport_manager::ConnectionUID connection_id) {
  // Add Device
  OnDeviceAdded(device_info);
  // Add connection
  OnConnectionEstablished(device_info, connection_id);
}
#endif  // BUILD_TESTS
}  // namespace connection_handler

redpajama_set_name: RedPajamaGithub


When requesting a local, long distance, or international move from a moving company in Herndon VA, consider Able Moving & Storage as your professional mover! Inherently, the moving business has a lot of particular details to be worked out, and as a result, this can be stressful to some. When working with us, you can rest assured knowing that we've got you covered from start to finish. Our business is licensed, bonded, and insured, and our movers are expertly trained and tested on their moving capabilities. We understand that relocating your home or office can be a scary experience, especially if you hire a company without taking the time to do your due diligence. Save yourself some time and many headaches by studying your prospective moving company's reviews and previous performances. You can also end your search for the best moving and storage company in Herndon Virginia by clicking below.
Narrowing down a moving service to complete your local or long distance move can be quite the process, especially if you're looking for the best mover in Herndon. Able Moving & Storage takes pride in earning repeat business. We constantly hear positive feedback from our customers, such as how easy and hands-off the moving process was when they left it to Able. Our moving services are designed to be easy, stress-free, and affordable. We've moved thousands of families in and out of the northern Virginia area. If you need help with your relocation, contact or call Able Moving & Storage. We're here for you. Our friendly staff is waiting for your calls and they're full of helpful information that will save you time and money on your move!
When it's time to relocate your belongings from Herndon to another area, consider calling Able Moving & Storage first for a simple and straightforward moving process. Letting our family owned & operated company handle your long distance relocation right from the start might be the best moving decision you ever make. We proudly stand behind our 30 years of experience in the moving industry.
Our long distance moving & storage division was started back in 1987 and has thrived ever since. Even if you don't schedule your move with us, our staff is full of helpful information that will help you find the right moving company for you. We're awaiting your call!
Able offers state of the art storage solutions for your items. We have three fully equipped storage facilities with more on the way, capable of holding all your belongings. We have an excellent long term and short term storage option for home and business owners. Whether you're moving your home or office, we have all of the solutions to provide you with the easiest move you've ever experienced. Our storage pricing is very flexible, and our terms are clear. We don't play games or change the rules after the fact.
We offer packing supplies such as moving boxes, bubble wrap, tape, wardrobe boxes, and anything else you could think of or need during the packing process!
What Are Our Herndon Moving Rates?
When shopping around for moving companies in Herndon Virginia, you'll more than likely come across several different prices for your move. In most cases, we can provide you with an over the phone estimate for your move, but if your home is larger than average, we suggest having one of our friendly estimators visit the home.
If you choose to have a quote provided by Able Moving & Storage, our estimator will visit your moving location and give an accurate estimate of the workforce and hours needed to complete your move.
We've moved thousands of families in and out of the area over the last 30 years. Before your move even begins, we have lots of helpful information to give you that will teach you more in depth about the moving service you'll receive with Able Moving & Storage. If you have any questions about our Herndon Virginia moving service, contact us during business hours!
Whether you own a small business or a large corporation, Able Moving & Storage Inc. has the perfect moving service for you. Office moves are one of our specialties, including local, cross country, and international services are offered. Wherever you plan on running your business or corporation, we are the Herndon movers to get you there. Our commercial moving experience dated back to our beginning back in 1987.
When planning your office move, hiring the right company can help alleviate issues with logistics, safe transportation of inventory, disassembly, and reassembly of furniture, and other surprises. Our process has been refined over our 30 years in business as you would expect. To help simplify your move, you will be assigned a moving coordinator from day one. Your trained and competent moving coordinator will be in charge of all the small details that can often get overlooked during a corporate office or small business relocation in Herndon. If you need more information about our office moving procedures, click here!
Choosing a moving company is an expensive decision to make, if you require more information about our Virginia moving services, please contact us today! We've been moving families for a long time; we are aware of the stresses involved with selecting the "right company." We want to make your moving process as simple as possible, and with our straightforward procedures, it's exactly that. When it comes to painless moving, the best and most obvious choice for your relocation is Able Moving & Storage. If you move with us once, you'll never have to search for another moving company again. We can handle any and all moves including local moves, long distance moves, international moves, and office moves.
Our professionally licensed Herndon moving services extend to the surrounding areas of Ashburn, Chantilly, Centreville, Leesburg, Sterling, and more!


The SPA3102 supports one RJ-11 POTS (Plain Old Telephone Service) FXS port to connect an existing analog phone or fax machine. The SPA3102 also supports one PSTN FXO port to connect to a Telco or PBX circuit. The SPA3102 includes 2 100BaseT RJ-45 Ethernet interfaces to connect to a home or office LAN, as well as an Ethernet connection to a broadband modem or router. The SPA3102 FXS and FXO lines can be independently configured via software controlled by the service provider or the end user.
Installed by the end user and remotely provisioned, configured and maintained by the service provider, each SPA3102 converts voice traffic into data packets for transmission over an IP network. Compact in design, the SPA3102 can be used in consumer and business VoIP service offerings including a full-featured IP Centrex environment. The SPA3102 uses international standards for voice and data networking for reliable voice and fax operation.
This device can be used in 3 different ways; Standard VOIP Line, Local Access Number Line, or both. We have configuration guides for each of the 3 ways you may want to configure your device.


text:
Q: Fastest approach for solving a modulo equation i should solve $a\cdot 57 \equiv_{39} 1$ for $a\in \mathbb Z$
My first idea was:
$a\cdot 57 \equiv_{39} 1 \ \ \Leftrightarrow \ \ 39 | (a\cdot 57 - 1 ) \ \ \Rightarrow \ \ a\cdot57-1=n\cdot 39\ \ \forall n \in \mathbb N \setminus \{0\}$
so we get: $a=\frac{n\cdot 39 + 1}{57},\quad \forall n \in \mathbb N \setminus \{0\}$
but since $a\in\mathbb Z$ this doesn't work.
Another approach would be splitting it into equivalence system of equations such that I can use the CRT, but that seems too much of a hassle for this exersice.
Another approach, also a bit CRT like, would be saying: There exists an x such that $0\leq x < 39$ then $a=x+39$. So we would get $57-39=18$ and we would have to solve $18x\equiv_{39} 1$ but this isn't really easier to calculate.
So, what's the fastest approach here?

A: I don't know if this is the fastest method, but a systematic way would be the Euclidean algorithm. Properly done, it yields numbers $a,n\in \mathbb{Z}$ such that $$57a+39k=1.$$
EDIT: Applying the Euclidean algorithm, you will finde $\mathrm{gcd}(57,39)=3$, hence $57$ is not invertible in $\mathbb{Z}/39\mathbb{Z}$ and there certainly cannot be $a,n\in \mathbb{Z}$ such that the above equation holds.

redpajama_set_name: RedPajamaStackExchange


text:
Jillian Bell Says The Channing Tatum Remake Of 'Splash' Is Still In The Works
Posted January 30th, 2019 by Jax Motes
Kathy Hutchins / Shutterstock.com
Jillian Bell co-starred in '22 Jump Street' with Channing Tatum and plans to re-team with him on a gender-swapped take on the 1984 comedy classic 'Splash'. In the original, Tom Hanks played a human that fell in love with a mermaid, portrayed by Daryl Hannah, who had legs on land and a tail in water. Obviously, in the new version, Tatum would be the merman, perhaps with Bell taking on the Hanks role. This remake was first suggested in 2015, after the release of 'Magic Mike XXL', but there has been very little news since then.
Bell is currently promoting her indie drama 'Brittany Runs a Marathon', but when asked about 'Splash', she offered a bit of an update:
"It's being written currently, so we hope we get to make it within the next couple years. I think it's happening. I'm really excited about it."
Remakes and reboots of '80s properties haven't been doing so well lately. Last year, the remake of 'Overboard' starring Eugenio Derbez and Anna Faris flopped. But that won't deter Hollywood, where remakes of everything from 'A Nightmare on Elm Street' to 'Terms of Endearment' is in the pipeline.
There also seems to be a sudden surge in mermaid-themed projects floating around, like the Freeform series 'Siren', which is returning for its second season, the indie thriller 'The Mermaid's Song', and Disney's big-budget live-action take on 'The Little Mermaid'.
If 'Splash' doesn't happen, it marks another high-profile project that Tatum just can't seem to get made, along with 'Gambit' for 20th Century Fox. However, even with the Disney buyout of Fox nearing finalization, this mutant flick may not be completely dead, as word has surfaced that Tatum still wants to make it and is even considering stepping up to direct, even after the film has already lost four helmers.
Since '22 Jump Street', Bell has appeared in the movies 'Goosebumps', 'Office Christmas Party', 'Fist Fight', and 'Rough Night', and the TV shows 'Workaholics', 'Dogs in a Park', and 'Idiotsitter'. She is also a busy voice actor, lending her pipes to 'Gravity Falls', 'The Angry Birds Movie', and 'Super Mansion'.
Are you interested in seeing a remake of 'Splash' with Tatum in the lead?
Source: Indie Wire
Josh Duhamel And Elena Kampouris May Headline Netflix's 'Jupiter's Legacy' Based On Mark Millar's Comic Book
Photos, Video, and Synopsis Of This Week's Episode Of 'The Orville: A Happy Refrain'
Evangeline Lilly Recalls Being "Cornered" To Perform Nude Scenes On 'Lost'
IMAX Delivers An Exclusive Teaser Trailer For 'It Chapter 2'
'The Conjuring' And 'It' Exec Producer Named New Head Of DC Movies For Warner Bros.

redpajama_set_name: RedPajamaCommonCrawl


text:
Find What You're Drawn To, Even if It's Hard
SUBSCRIBE WITH iTUNES SUBSCRIBE WITH YOUTUBE SUBSCRIBE WITH STITCHER
Download The Podcast MP3
Paul isn't much older than I am.
But I feel like I've been watching him on TV and in movies since I was born.
We laughed about that.
Paul's been doing stand up since he was 17 years old. Paul remembers watching the comics when he was little. It spoke to him on a different level than the Beatles or any of the other rock stars of the time.
Paul when to college, but then he after he graduated he took the nonlinear life path.
The path I feel like everyone should try out at least once in their lives.
He moved to the city and he started hanging out in clubs. He was making four dollars an hour.
But his parents were scratching their heads, why would you want to be a comedian?
They wanted him to be just about anything else. It was just too risky. And it was hard.
There were no paychecks, no benchmarks. It was an unimaginable world to his parents.
There's no reason anyone should ever make it as a comedian.
But he did it anyway.
And I wanted to know what the initial appeal of stand up was for Paul.
"For a comedian, I don't think you can do anything else. You're drawn to it. And when you're starting out as a comic you're protected by an ignorance of youth. If you knew how bad you were, you wouldn't dare go up," Paul said.
Paul made his first appearance on the Johnny Carson Show in 1982. The comedian's stamp of approval. Even if they've never heard of you, they've heard of Johnny Carson. This was his in.
The stamp of approval he'd been waiting for.
His career was finally starting to come together.
It helped him get into acting. You may remember him in "Mad About You" or "My Two Dads" or "Diner".
But he always meant to get back to stand up. It just never happened because he was too busy and distracted with so many other obligations. But he told me this: it's not going to happen unless you do it.
So he started little by little each day. He started to find who out who he was again. And he found his voice. He started to grow back into a comedian each day.
"What I love about stand up is it's a moving target. It's like a horizon. You keep moving towards it and then it keeps moving. There's always so much more I have to learn. You never feel like you've arrived in the best sense," Paul said.
He loves what he does and he keeps improving each day.
He showed me how to keep getting better. And to never stop doing what you love.
When in doubt, just do it. Don't question what you're drawn to.
Move towards the target.
Links and Resources:
Watch Paul in My Two Dads
Watch Paul in Mad About You – He was in 160 episodes!
Watch Paul in Diner
Watch Paul's first appearance on "The Tonight Show with Johnny Carson" in 1982!
Watch There's…Johnny! Paul wrote the Hulu Original Series!
Paul stars in the TV Series Red Oaks, he describes it as Caddyshack meets The Graduate
Watch Paul in Stranger Things
Read Paul's Books:
Couplehood
2000 Year Old Man Record
Harold Ramis on Caddyshack 30 Years Later
Thanks so much for listening! If you like this episode, please subscribe to "The James Altucher Show" and rate and review wherever you get your podcasts:
Book Recommendation 46
Inspiration 40
Impression Technique 27
Ambition 10
Ep. 208:…


Every great relationship needs understanding and clear communication.
Our project inquiry form is our get-to-know tool that is constantly evolving to pull the right information about your project to help us serve you with excellence. Thank you for taking this leap to start your project off with us the right way.
What are 3 things your site does well?
What are 3 things you would like to change about your site?
Is there anything in particular you want on your site?
Please tell us about your business?
Who is your business' intended audience?
What types of services would you like us to provide?
What are you favorite websites? Why do you like them?
What is the ideal tone for that represents your brand?


STAREAST – SmartBear Software, provider of software quality tools used by more than one million developers and testers worldwide, is redefining large-scale Web optimization with LoadUIWeb Pro, its new, affordable Web performance testing tool. This new commercial version, released a few weeks after strong interest in the free LoadUIWeb tool, addresses the needs of enterprise and large website teams with advanced capabilities and support at an affordable cost.
While LoadUIWeb appeals to a large cross-section of performance engineers, enabling easy set up and affordable performance testing, the Pro version includes features and capabilities that are essential for larger organizations, popular websites with worldwide audiences and Web teams that need to optimize performance. Best of all, the Pro version meets the needs of enterprises without breaking the bank, following SmartBear's commitment to provide affordable, high-quality tools to the growing devops community.
LoadUIWeb Pro offers all the convenience, simplicity and intuitiveness of the free LoadUIWeb. Load testers using the Pro version can generate up to 20,000 virtual users; distribute loads across geographic regions and get region-specific performance metrics; support performance diagnostics via server monitoring; and improve productivity through automation and context-sensitive UI wizards.
LoadUIWeb Pro is part of SmartBear's commitment to driving software quality. It joins the company's performance-oriented product family that also includes AQTime for application profiling, LoadUI for API load testing, and AlertSite and API Monitoring for performance monitoring.
Visit Booth #51 at STAREAST to experience LoadUIWeb Pro. For information or to trial LoadUIWeb Pro, visit: http://loaduiweb.org/go-pro/top-reasons-to-go-pro.html.


Do you need nuclear physics help? We will be pleased to offer our service for the same. We confirm that our nuclear physics help is well-intentioned and are of special attention too. Within a short span of time, we react on nuclear physics assignments, homework, etc. with immense pleasure. So, without hesitating, you can contact our experts for help.
Nuclear physics is the part of nuclear power, archaeology, nuclear weapons, engineering, and medical science. It is also a section of physics that examines atomic nuclei. Nuclear physics assignments frequently involve the nuclear fission, radioactive decay, nuclear fusion, and physics. Nuclear physics assistance may be required for formulas or theories. The study hasbeen conducted before, like Rutherford's studies, Yakawa's investigations or James Chadwick's work. Students face nuclear physics problems during their degree program.So, they seek help with Nuclear physics to complete their nuclear physics homework assignments. They attain nuclear physics help from our qualified writers. Our expert writers have owned their degrees in their respective field. Students can take help with nuclear physics from our experts, whenever they face any difficulties.
Our expert writers have the real-time experience to solve nuclear physics homework online. So, they can provide excellent support in nuclear physics assignment writing. Since this subject of nuclear physics is too complex to understand for the students, so it is beyond their imagination to solve nuclear physics assignments. By using our best possible assistance,they can meet the deadlines for nuclear physics assignments online from our professional high-quality writers who want to see them succeed with their degree program. Scholars can fulfill their dream to complete a degree with excellent grade by availing our nuclear physics help.
Our squad works for 24-hours a day, throughout the year for the needy students who face any difficulties in nuclear physics assignment. Our experts provide with excellent nuclear physics assistance to complete their papers and offer them with a solid groundworkto achieve grade "A" on nuclear physics assignment. All our writers have the practical experience in their fields and are the professional academic writers with degrees of their own.They have completed several nuclear physics assignments on which the students seek help now.The quality experience of our experts assuresthe students to providethem with top quality nuclear physics help irrespective of the type of the nuclear physics assignment they are solving. We always deliver a unique and correct solutionwithin the scheduled time.
Students pursuing their degree are found seeking nuclear physics solutions for their nuclear physics assignment. They are always suggested to visit our website and go through the sample assignments provided. To get the top-quality nuclear physics help for all your nuclear physics assignment solutions they are suggested to trust our writers. So, why to waste further time? Avail our nuclear physics help to achieve your dream. Submit your assignment now and contact our executives via email or live chat.


10 years ago when my husband and I adopted a puppy, we began to detox and simplify our home. Concerned about all the harsh chemicals in our household cleaning products we began our journey to natural living with these green living essentials. I've found that keeping things simple not only is safer for our family but saves quite a bit of money.
I know sometimes it can be hard to see the big picture, especially if we are just making one natural recipe at a time. Which, is perfectly OK. In fact, I highly recommend you replace products in your home as you use them up. For example, when you use the last of your commercial dust spray, make Lemon Cedarwood Dust Spray. Use it and when you run out of another cleaner, make it.
Instead of trying to overhaul your entire cleaning closet at once. The later could likely lead to overwhelm and cost a lot upfront to make. As you start to make more household cleaners and natural skincare products, you will begin to see the big picture. Which is, most basic ingredients overlap into creating multiple products.
Another wonderful thing about sustainable, green living is having less waste! You'll be surprised at how slow your rubbish bin will fill when you stop buying paper towels! Microfiber towels work so much better for cleaning anyway. And cloth napkins can feel like a luxury, even if you make them from fabric scraps or traditional flour sacks.
Glass jars, such as mason jars and glass bottles which you can top with spray nozzles or pumps, can be reused time and time again. I compiled the list below of 20 must have green living essentials as a guide. I've included a link where possible for reference.
You'll need a variety of cleaning spray bottles to overhaul your cleaning closet. And if you are planning to include any citrus essential oils, such as lemon essential oil in your DIY cleaners you'll want to use glass bottles only. This starter set of 15 amber glass bottles is the way to go!
If you're going green then, it's time to stop the paper waste. That's right no more paper towels or wipe cleaners. Believe it or not, you'll save money by picking up just one set of microfiber cleaning cloths or 100% Natural Cotton Dish Towels.
Castile soap is a concentrated vegetable-based soap made of ingredients you can actually pronounce. This soap is gentle on skin and effective against dirt, grease, and unwanted germs. Castile soap can be used to clean just about anything and everything: your face, your shower, and even your dirty dishes! Yes, I'm a fan!!
Baking soda, also known as sodium bicarbonate, is a naturally occurring substance. Best known for its use as a scouring agent and odor absorber. Baking soda is also used in cleaning recipes to fight against dirt, grease, and odors. This clean agent alone is a must-have for your cleaning arsenal, I buy it in a one pound bag here.
Essential oils not only provide a wonderful natural fragrance to homemade cleaners but also contain powerful disinfecting properties. If you've been wanting to learn how to clean with essential oils, read more here for tips on choosing the best essential oils to clean your home naturally.
Reduce plastic waste by using glass pump bottles for practical everyday use. Fill them with natural hand wash and lotion to keep at your bathroom and kitchen sinks. I use one for my DIY aloe vera face wash too.
Vinegar contains 5% acetic acid that fights against bacteria on your surfaces. Although, because vinegar is acidic, it can cause some etching on granite, marble, or stone surfaces. Test it an inconspicuous area or substitute rubbing alcohol for vinegar when needed. Regardless of its limitations vinegar is a great all-purpose tool for your natural cleaning toolbox.
Body butter comes in a variety of textures rich and thick, soft and creamy, each with purpose and benefit for the skin. They are all from natural sources such as kernels and fruit trees. Body butter can be used in soaps, lotions, lip balms, body washes, and creams. Each is solid at room temperature with different melting points. Learn all about how to use natural body butter here.
Swapping traditional glass mason jars for plastic containers is another great method to reduce plastic waste. I use them to store dried herbs from the garden, freshly squeezed juice, and bath bombs and well just about anything! Start with a pack of 12 pint-sized mason jars.
Thanks to Epsom salts, bath bombs do much more for our bodies than moisturizing the skin. Named after a small town in England where it is was discovered in 1618, Epsom salts are known for their powerful ability to relieve aches and pains. They breakdown the build-up of lactic acid which causes muscle pain. Add a ½ cup of Epsom salt to your next bath or try them in my recipe for a bubbling lemon vanilla bath soak.
Natural waxes like soy, beeswax, and coconut are excellent sources for candles. In fact, you can make a half dozen soy wax candles at home in just an hours' time all while leaving the carcinogens out! Soy wax is non-toxic, biodegradable, renewable, and cleans up if spilled with just warm water. Combine it with a pack of wood wicks, candle tins, and a DIY recipe for apple blossom soy candles.
Yep, we're talking about rubbing alcohol, isopropyl alcohol, and straight up vodka. Just don't use your husband's fancy vodka – go for the cheap stuff! Vodka's high alcohol content happens to be perfect for killing germs, and even mildew or mold. And all of the above really help shine chrome and glass in addition to killing odors. Plus you'll find each is antiseptic.
I love having fresh herbs within in reach to use in my beauty recipes. Even if you don't have a green thumb you certainly keep the plant alive long enough to get your money worth or opt for dried herbs. Fresh herbs not only make our homemade beauty recipes smell heavenly, but they also have a multitude of benefits. Chamomile, eucalyptus leaves, lavender, and lemon balm are some of the favorites to use.
Natural carrier oils can make a big impact on the health and condition of your skin. They are packed with vitamins and antioxidants essential for healthy skin. There are a variety of carrier oils available such as apricot kernel oil, grapeseed oil, sweet almond oil, and more – find the right carrier oil for your skin type here.
Sal Suds is Dr. Bronner's tougher version of soap, although its chemical makeup makes it a detergent, not a soap. Sal Suds is formulated to conquer tough cleaning projects such as unforgiving grease and stubborn dirt. And the Environmental Working Group gives it an A. Sal suds is basically a tougher version of castile soap. So, do not use it for skin applications.
Goat milk soap base is specially formulated to suspend additives evenly throughout soap. Meaning if you add lavender buds or chamomile flowers from the garden to your homemade soap they won't sink to the bottom of the soap like it would in other soap base types. It also a natural skin-loving choice for making soaps. Try in my recipe for lavender goat milk soap.
This may seem like an odd addition to a green living essentials list, but loose leaf tea is quite handy for natural beauty and hair care. I love to add herbal teas to soaps and bath tea recipes. You can simply drop five tea bags into your bath for quick use or make a rich spiced chai latte bath for relaxing self-care treat.
Washing soda, also known as sodium carbonate is extremely alkaline. The high alkaline level works as solvent or water softener to degrease and lift stains. It very effective to fight hard water because it binds to the minerals. Washing soda also helps liquid soap "gel", making it a multipurpose cleaning tool.
Use this handy printable market list to keep track of your green living staples. Grab it and many more printables and reference guides in the Life-n-Reflection Resource Library.
Now that you've got your market list, you may be wondering what to make versus buying? Browse my Natural Skincare Recipes and Natural Home Recipes. Grab my best selling book Aromatherapy: A Practical Guide for Home and Family!


Ironclad Games and Stardock are pleased to announce the release for version 1.94 of Sins of a Solar Empire: Rebellion. This latest update contains a number of balance changes and enhancements.
NPC, Rampant Militia, and Minor Faction ships will now upgrade their abilities as they gain experience (if they have abilities to upgrade).
Pirates no longer stay in a fleet when they arrive at their target planet. This allows them to be more effective at raiding the enemy defenses.
Only Pirate Rogues now place tradeships at the top of their target priorities. If there are enemy dps units/structures in the gravity well, every other pirate ship will engage those first before raiding tradeships.
Changed Scrap For Parts ability to refund 60/75/90% of the targeted ships' build cost rather than give credits per fleet supply.
Minor Factions now have occupy all resource asteroids for the default planet definitions.
Fixed a bug in scuttling that caused the salvage percentage to be applied twice (e.g. normal salvaging now correctly refunds 30% instead of 9%).
Fixed incorrect player stats being tallied for Minor Faction and Rampant Militia units (e.g. when they kill units they don't contribute to the owner player stats).
Fixed incorrect player stats being tallied for structures (e.g. Minor Faction created structures shouldn't contribute to the owner player stats).
Fixed partially built Minor Faction structures not being scuttled when the planet became unowned. The Minor Faction's constructors likewise now properly self-destruct in that situation as well.
Fixed bug where structures created by a buff in the orbit of an Minor Faction planet would assume the Minor Faction's ownership index (e.g. ability created phase gates).
Fixed bug where a player could own Minor Faction construction ships.
Fixed bug where Minor Faction capital ships count towards your total labs as Vasari Loyalist.
Fixed bug where the first Minor Faction lab you capture doesn't count towards your total.
Fixed bug where the "Send Envoy" quest was being trivially completed.
Fixed a bug where the wrong capitalship/frigate could be built by a Minor Faction if both the construction frigate and factory had previously been destroyed.
Fixed ships physics from being disabled when they died.
Fixed Occupation Victory win condition from potentially crashing and if not crashing, potentially not colonizing the planet.
Fixed bug where icons weren't showing up around a planet on some maps (e.g. DogFight).
Fixed bug where skybox and music transitions were incorrect.
Fixed rare 'zoom to infinity' bug.
Fixed a bug in the calculation of planet bombing damage that was causing it to be roughly twice as high as it should have been.
Fixed resource extractors from not transferring after acquiring a minor faction planet.
Fixed respawned minor faction ships from not assuming their minor faction status.
Added custom per-unit hyperspace effects. If a unit does not define them the player effects are used by default. Refer to Capital_PhaseBattleship.entity as an example of how to set custom effects up.
Fixed the bug where NoPlanetOwner conditions and its variations would fail due to template-based colonization and item creation being split into separate passes (since if the planet got colonized, it would now have an owner when the condition got re-evaluated in the item pass).
Increased max exhaust trails to 5. Added block and warning if anyone attempts to exceed the max to avoid stomping on valid memory.
Removed some asserts in buffs that aren't valid - depending on the buff chain and game state it is sometimes legitimate for first and last spawner to be null.
Fixed potential crash with ApplyBuffToTargetWithNoFilter.
Fixed warnings/potential crash when accessing a squad definition if there were none defined.
Fixed a variety of string issues.
Fixed LAA problems with shaders.
Removed some duplicate entities, brushes, sounds, and strings.
Removed some references to non-existent resources.
Fixed achievement issues created by Minor Faction and Rampant Militia units.
Fixed achievements not showing up in game at all under certain conditions.
Fixed crash bug that was caused by the ship cost querying not robustly handling a playerIndex of -1. This can occur if the player is interacting with the ship construction action grid as they lose ownership of the planet.
Fixed spawn all entities from crashing.
Item templates now properly use the playerIndex parameter when creating structures instead of assuming it will be the planetOwner.
Fixed building a structure not always using the correct player owner.
Fixed crash when querying tooltip for abilities that used new atomics.
Fixed bug where the wrong default player type was being saved.
Removed Galaxy Forge's copy of galaxyscenariodef which can go out of sync. Reads from the game's copy now.
GalaxyForge now searches the local directory for GSD before checking GameInfo.
Updated to read new data format.
Remove Particle Forge's copy of the pipelineeffects which can go out of sync. Reads from the game's copy now.
ConvertData now maintains Simple brushes if possible.


text:
In the 1970s, the journalist Anand Giridharadas' parents moved from India to America for better professional opportunities, leaving behind India's stagnant economy and rigid caste system. Three decades later, their America-born son moved back to an India with a free market going full tilt and intense social mobility changing the face of the nation.
In his debut nonfiction book "India Calling: An Intimate Portrait of a Nation's Remaking"(Times Books, 274 pp., $25), Giridharadas weaves his family history in with the stories of contemporary Indian strivers like Ravindra, an entrepreneur who pulled himself out of grinding poverty through the can-do maxims of Dale Carnagie, and Mukesh Ambani, a billionaire whose aggressive economic dealings are reshaping the country and the Indian identity at the same time. Readers will meet Indian women who reject arranged marriages and a Maoist rebel still fighting after five decades. Giridharadas' portrait of a modern India is vivd and optimistic, cataloging the the country's growing economic power and turbulent changes.
Giridharadas, 29, was raised in Ohio and Maryland. He is a columnist for the International Herald Tribune and spoke with freelance writer Dylan Foley by telephone from his home in Cambridge, Mass.
Q. Why did you incorporate much of your family history of emigrating from India to America in this book?
A. It was something that emerged quite late in the process. The big story I am telling was what India was to itself and the world, and what India is now. In the larger story of change, I thought it would be interesting to tell my family's story of change. It was a way of making a big story smaller.
Q. In one of your essays, you write about Ravindra, a man from an oppressed Indian social class in a small town in the center of India who started several businesses. How did he reinvent himself?
A. The essence of what Ravindra did was from a series of revelations. Revelation number one was waking up in his serf-like childhood and realizing he did not have to be a serf. Nobody in his family had ever had that insight. Number two was deciding to self-educate rather than depend on the system. Don't trust that anyone will help you. The third revelation was that he was not alone, that there were millions like him who wanted to change their lives. Ravindra offered others the services of self-invention., like running his skating school, and profited from them. He understood how profoundly ordinary his own dream were.
Q. Americans living in India often find themselves uncomfortable with the Indian upper-classes' treatment of their servants. What was your experience?
A. When you first arrive in India, you think, "God, these Indians treat their servants so badly! How awful!" It's something in the air and something about the way people are, that very few people hold out. I wasn't able to. Everybody goes local. You stop saying "thank you" and things like that. I was disappointed with myself that I crossed the line where you accept the concept that employers and servants come from different worlds.
Q. In one story you tell, two brothers split the family home, becoming Upstairs Uncle and Downstairs Uncle to their niece, showing the rifts in modern India in one building. What did you learn?
A. The Upstairs Uncle broke away from his brother and family because he was more ambitious. He literally built another home on top of the family house. What happened across the Upstairs/Downstairs gradient was that the fault lines of modern India were bared. There were different conceptions of family love and romantic love, as well as a different understanding of self, money and ambition between the two families. About all, there was a different understanding of family obligation. You got to see this in one house how all these things manifested themselves.
(This interview ran in the Newark Star-Ledger in March 2011)
Posted by Dylan Foley at 12:47 PM
Labels: Anand Giridharadas, India Calling


Thanks for accepting, Tex. ..Wishing you many happy trails.
A very proper way to reply to my remark, Tex! Tell your Dawg he has every right to be aware of his radiance!
Absolutely beautiful dog you have there, Tex!
Used to be, I would spend my summers in northern Spain. We would see Great Pyrenees (I am assuming that is what your beastie is) guarding the livestock. They would always come over to check us out and say hola. Really cool dogs.
Tex, thanks for sending me that little piece of wisdom and hope. Most of it has been true for me and mine already. We can only hope for more. Thanks again.
Thanks, Tex. It's a long road.
Thanks for the shout out Tex.
Tex, believer is here. He just doesn't come around a lot. He is known here as D.
Hi Tex . Good to see you here . I've enjoyed your folksy commentary for a long time on the vine .
Check your Inbox Tex. It's in the box on the top right of this page. You've got mail.
Hey Tex, is that Tex-988483? Welcome to NewsTalkers.


text:
info@eternalcremations.org
Direct Cremation Services Provider
7 Amazing Reasons You Should Visit Detroit Opera House
Detroit Opera House is a beautiful building located in the heart of Detroit MI. It's a popular tourist attraction that many people visit for its architecture and history.
The opera house was opened on October 20, 1922, with a production of "Faust" starring Marguerite Namara, which was attended by President Warren G Harding. Not only is it an important piece of history but also has an extremely rich architectural design with Byzantine-style details including mosaics, paintings, and even marble statues.
Here are seven amazing reasons you should visit Detroit Opera House:
1. Architectural marvel
The architecture of the opera house is one reason why people visit. It was designed by architect C. Howard Crane also designed other theaters around the world including Radio City Music Hall and Fox Theater in Detroit, and State Theater in Cleveland, Ohio.
2. Rich history
The building has hosted numerous presidents, prime ministers, and royalty throughout the years. There are also many famous conductors to have performed there including Arturo Toscanini, George Szell, Grace Bumbry, and Sarah Caldwell.
3. Experience world-class performances
The theatre is recognized for its high-quality productions in opera, ballet, and musical theater since opening its doors over 90 years ago. Many of the leading dancers have graced the opera house's stage including Natalia Makarova, Mikhail Baryshnikov, and Rudolf Nureyev just to name a few.
4. Extensive Art Collection
From ceiling mosaics to sculptures there are 19 art panels dedicated to different themes throughout Detroit Opera House which are all fascinating pieces of artwork to see.
5. Detroit's Cultural Landmark
In 1978, the opera house was registered as a National Historic Landmark by the United States Department of Interior and is one of only six theaters in the country to receive this honor.
6. Iconic building
The opera house is an iconic part of Detroit's skyline and can easily be seen from a distance. The foyer of the opera house is a great place to take photos and get an up-close look at the intricate artwork including mosaics, paintings, and statues.
7. Spectacular performance
The lighting in front of the Detroit Opera House during Christmas time has been featured on national television which makes it a great photo opportunity for visitors.
In conclusion, the Detroit Opera House is a beautiful building with an important history and exquisite architectural details that everyone should visit when in the city. Detroit Opera House is a popular tourist destination in Detroit due to its rich history, architectural marvels, world-class performances, extensive art collection, iconic buildings, and spectacular performances.
Detroit Cremation Services
Grand Rapids Cremation Services
Benjamin Franklin Parkway
Little Caesars Arena
© 2021 All Rights Reserved eternalcremations.org


The Native American story of the Sky Elk. Learn about the culture, stories, myths and legends of American Indians and their famous chiefs and tribes.
A Native American Story of the Sky Elk to teach kids about Native Indians in a short, enjoyable, easy to read format.
A mighty hunter was Sosondowah. His form was lithe, his step noiseless, and his hair black like the Crow's wing. His keen eyes saw every track made by wild things, and he knew the songs of birds and the calls of all creatures. He roved through the forest, his bow bent, and his feathered arrow ready for flight, his soft step never stirring a leaf nor breaking a twig.
One day in the hush of the noon hour, he forced his way through a thicket, and entered a glade encircled with trees and fringed with low bushes. And under an Oak, in the centre of the glade, he saw a great Sky Elk that had escaped from the Elk grazing-fields that shine far beyond the path of the Sun. It was turning its watchful eyes from side to side. It was dusky and huge like a shadow, and its spreading antlers brushed back the boughs of the Oak.
And when Sosondowah saw the Sky Elk, his eyes flashed, and he made ready to shoot. But first in order to obey the law of the forest,—which commands hunters to warn a beast before shooting so that it may have a chance to escape,—he shook a small sapling, and its rustling leaves bade the Sky Elk flee for its life.
The animal heard the sound, and, lifting its head, snuffed the air. Then with a snort it bounded away. Through the tangled paths of the forest it fled, pursued by Sosondowah's swift arrows. But as the arrows struck the dusky sides of the Elk, they fell blunted and harmless to the ground.
Unwounded, the animal hastened on hour after hour. Along forest paths and through meadow land it sped, up hills and down into valleys it ran, and it leaped streams and ravines. And after it with swift, noiseless feet Sosondowah followed.
The noonday passed, the afternoon waned, the sunset painted the Western Sky, darkness fell, the Moon arose and cast mocking white beams on the land. But ever, like a winged shadow, the Sky Elk silently fled before, and Sosondowah, shooting his feathered arrows, followed after.
And when the Sky showed that day was near, and the Dawn Maid arose and began to paint the East with the red plumes of light, the Sky Elk quickened its pace. Reaching the edge of the world, it leaped up the rosy-white cloud-hills, and hastened to the Dawn Maid's lodge in the Land of the Early Red Morning.
When Sosondowah saw this, he caught hold of the wing of a Night-Bird that soared with him into the Sky. And as he went up he shot many sighing arrows from his bow. Then the evil Night-Bird suddenly shook Sosondowah from its wing, and he fell toward the Earth.
But the Dawn Maid from her lodge saw him fall, and, stretching out her arms, caught him, and drew him safely into the Land of the Early Red Morning. She placed him at the door of her lodge, and commanded him to watch and guard it forever.
But Sosondowah never saw the Sky Elk again, for it had returned to the Elk grazing-fields that shine far beyond the path of the Sun.
The Native American Indian Story of the Sky Elk provides an opportunity to read about the life and times of Native American Indians and many of their great chiefs and famous leaders. A Classic Short story about Sky Elk for kids and children of all ages. This short story of the Sky Elk is great to read to kids and children at bedtime. This very short story contains folklore about the famous people of Native Indian tribes.
This short Native American story has been selected to keep the attention of kids and children of all ages. Many of the traditional stories featured in this section are true and others are folk stories or myths and legends. Read our free short story online about Sky Elk. Read a free, online short story about the people of famous tribes Native American Indians to increase knowledge and understanding of the indigenous people of North America.
The Story of the Sky Elk. Discover the vast selection of pictures which relate to the Stories, History and Culture of Native Americans. The pictures show the clothing, War Paint, weapons and decorations of various Native Indian tribes that can be used as a really useful educational history resource for kids and children of all ages. We have included pictures and videos to accompany the main topic of this section - The Native American story of the Sky Elk. The videos on this website enable fast access to the images, paintings and pictures together with information and many historical facts. All of the articles and pages can be accessed via the Native Indian Tribes Index - a great educational resource for kids.


The soft, leather, drawstring Leather Accessories Pouch with Stow gold-toned hardware makes an excellent, small tech holder and is perfect for storing glasses, charging cables and change.
Designed to suit everyone, the Leather Accessories Pouch makes an ideal Christmas or Anniversary gift.
Designed in the UK - hand-crafted by Spanish artisans.


We are pleased to announce that Conor Dale, a final year undergraduate student of our BA(Hons) Business Management programme, has secured a prestigious Institute of Chartered Accountants in England and Wales (ICAEW) training contract with Larking Gowen in Ipswich. Suffolk Business School prides itself on its ability to help create Business Ready Graduates. Conor's success helps to illustrate our excellent employment/further study rate for our students after graduation, and the dedication of our lecturers in supporting the employability of our students.
We have attended numerous UCS events and found these to be a very helpful source of potential candidates. Larking Gowen can offer excellent long term opportunities within the competitive professional services sector and are keen to attract and retain the best local talent and support their career development in Suffolk.
During my time at UCS I have thoroughly enjoyed all aspects of the course, and lecturers have made each module enjoyable in their own way. I received the support I needed at every stage of the application process to Larking Gowen from my tutor, Dr Atul Shah.
I chose a career in accounting because I enjoyed the accounting modules that I took immensely and excelled in them. These factors meant that it felt like the clear next step to pursue a career in accounting.
At UCS our approach is holistic – we want to help students get ignited from within, so that they make a great life career. And we support them in their career choice after graduation, not just leave them on their own when they graduate. We recognise that learning is not simply about facts and theories, but more importantly about motivation, meaning and purpose. Finance is a skill that every person needs to negotiate the complexities of modern life, and we help students build that knowledge with confidence.
Posted on March 24, 2016 May 17, 2016 by ucssbsPosted in Business, Employers, Students, UCS, UncategorizedTagged Employability, Employers, Finance, Larking Gowen, Students, Suffolk Business School, Training Contract.


The watersheds of the Tongass National Forest support abundant and diverse populations of wildlife, including some species that are found nowhere else in the world and several species that have experienced population declines in the southern portion of their ranges. Over 70 species of mammals large and small are found in the Tongass, including more brown bears than the entire Lower 48 states combined, as well as black bears, wolves, squirrels, and martens. The watersheds of the Tongass also play host to moose, mountain goats, and Sitka black-tailed deer.
In addition to the mammals, over 275 bird species (including 150+ breeding species) utilize the watersheds and coastlines of the Tongass national forest. The Tongass is home to the highest nesting density of bald eagles in the world, with some 7000 adult eagles inhabiting the Tongass year-round and another 5000+ non-breeding and juvenile eagles migrating south to Washington and Oregon for the winter.


text:
<< Previous TITLE 29 / CHAPTER 16 / GENERAL PROVISIONS / § 712 Next >>
29 USC 712: Information clearinghouse Text contains those laws in effect on January 18, 2020
From Title 29-LABORCHAPTER 16-VOCATIONAL REHABILITATION AND OTHER REHABILITATION SERVICESGENERAL PROVISIONS
Jump To: Source CreditReferences In TextPrior ProvisionsAmendments
§712. Information clearinghouse
(a) Establishment; information and resources for individuals with disabilities
The Secretary of Education shall establish a central clearinghouse for information and resource availability for individuals with disabilities which shall provide information and data regarding-
(1) the location, provision, and availability of services and programs for individuals with disabilities, including such information and data provided by State workforce development boards regarding such services and programs authorized under title I of such Act; 1
(2) research and recent medical and scientific developments bearing on disabilities (and their prevention, amelioration, causes, and cures); and
(3) the current numbers of individuals with disabilities and their needs.
The clearinghouse shall also provide any other relevant information and data which the Secretary of Education considers appropriate.
(b) Information and data retrieval system
The Commissioner may assist the Secretary of Education to develop within the Department of Education a coordinated system of information and data retrieval, which will have the capacity and responsibility to provide information regarding the information and data referred to in subsection (a) of this section to the Congress, public and private agencies and organizations, individuals with disabilities and their families, professionals in fields serving such individuals, and the general public.
(c) Office of Information and Resources for Individuals with Disabilities
The office established to carry out the provisions of this section shall be known as the "Office of Information and Resources for Individuals with Disabilities".
(d) Authorization of appropriations
There are authorized to be appropriated to carry out this section such sums as may be necessary.
(Pub. L. 93–112, §15, formerly §13, as added Pub. L. 105–220, title IV, §403, Aug. 7, 1998, 112 Stat. 1113 ; renumbered §15, Pub. L. 105–277, div. A, §101(f) [title VIII, §402(a)(1)], Oct. 21, 1998, 112 Stat. 2681–337 , 2681-412; amended Pub. L. 113–128, title IV, §407(b), July 22, 2014, 128 Stat. 1639 .)
Such Act, referred to in subsec. (a)(1), probably means the Workforce Investment Act of 1998, which is Pub. L. 105–220, Aug. 7, 1998, 112 Stat. 936 , and was repealed by Pub. L. 113–128, title V, §§506, 511(a), July 22, 2014, 128 Stat. 1703 , 1705, effective July 1, 2015. Title I of the Act was classified principally to former chapter 30 (former §2801 et seq.) of this title. Pursuant to section 3361(a) of this title, references to a provision of the Workforce Investment Act of 1998 are deemed to refer to the corresponding provision of the Workforce Innovation and Opportunity Act, Pub. L. 113–128, July 22, 2014, 128 Stat. 1425 . For complete classification of the Workforce Investment Act of 1998 to the Code, see Tables. For complete classification of the Workforce Innovation and Opportunity Act to the Code, see Short Title note set out under section 3101 of this title and Tables.
Provisions similar to this section were contained in section 714 of this title prior to repeal by Pub. L. 105–220.
A prior section 712, Pub. L. 93–112, §13, as added Pub. L. 95–602, title I, §122(a)(10), Nov. 6, 1978, 92 Stat. 2985 ; amended Pub. L. 98–221, title I, §102, Feb. 22, 1984, 98 Stat. 17 ; Pub. L. 99–506, title I, §105, Oct. 21, 1986, 100 Stat. 1812 ; Pub. L. 102–569, title I, §§102(p)(4), 106, Oct. 29, 1992, 106 Stat. 4356 , 4362; Pub. L. 104–66, title I, §1042(c), Dec. 21, 1995, 109 Stat. 715 , related to reports to President and Congress, prior to repeal by Pub. L. 105–220, title IV, §403, Aug. 7, 1998, 112 Stat. 1093 . See section 710 of this title.
A prior section 15 of Pub. L. 93–112 was renumbered section 17 and is classified to section 714 of this title.
Another prior section 15 of Pub. L. 93–112 was classified to section 714 of this title prior to repeal by Pub. L. 105–220.
2014-Subsec. (a). Pub. L. 113–128, §407(b)(1)(A), inserted "of Education" after "Secretary" in introductory and concluding provisions.
Subsec. (a)(1). Pub. L. 113–128, §407(b)(1)(B), substituted "State workforce development boards" for "State workforce investment boards".
Subsec. (b). Pub. L. 113–128, §407(b)(2), substituted "Secretary of Education" for "Secretary".
1 See References in Text note below.