text:
using drive::DriveSystemService;
using drive::DriveSystemServiceFactory;

namespace chromeos {

namespace {

// The minimum session length limit that can be set.
const int kSessionLengthLimitMinMs = 30 * 1000;  // 30 seconds.

// The maximum session length limit that can be set.
const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000;  // 24 hours.

// Time delay for rechecking gdata operation when we suspect that there will
// be no upcoming activity notifications that need to be pushed to UI.
const int kGDataOperationRecheckDelayMs = 5000;

ash::NetworkIconInfo CreateNetworkIconInfo(const Network* network) {
  ash::NetworkIconInfo info;
  info.name = network->type() == TYPE_ETHERNET ?
      l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET) :
      UTF8ToUTF16(network->name());
  info.image = NetworkMenuIcon::GetImage(network, NetworkMenuIcon::COLOR_DARK);
  info.service_path = network->service_path();
  info.connecting = network->connecting();
  info.connected = network->connected();
  info.is_cellular = network->type() == TYPE_CELLULAR;
  return info;
}

void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime,
                    const input_method::InputMethodUtil& util,
                    ash::IMEInfo* info) {
  info->id = ime.id();
  info->name = util.GetInputMethodLongName(ime);
  info->medium_name = util.GetInputMethodMediumName(ime);
  info->short_name = util.GetInputMethodShortName(ime);
  info->third_party = ime.third_party();
}

gfx::NativeWindow GetNativeWindowByStatus(
    ash::user::LoginStatus login_status) {
  int container_id =
      (login_status == ash::user::LOGGED_IN_NONE ||
       login_status == ash::user::LOGGED_IN_LOCKED) ?
           ash::internal::kShellWindowId_LockSystemModalContainer :
           ash::internal::kShellWindowId_SystemModalContainer;
  return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
                                  container_id);
}

ash::DriveOperationStatusList GetDriveStatusList(
    const google_apis::OperationProgressStatusList& list) {
  ash::DriveOperationStatusList results;
  for (google_apis::OperationProgressStatusList::const_iterator it =
           list.begin();
       it != list.end(); ++it) {
    ash::DriveOperationStatus status;
    status.file_path = it->file_path;
    status.progress = it->progress_total == 0 ? 0.0 :
        static_cast<double>(it->progress_current) /
            static_cast<double>(it->progress_total);
    status.type = static_cast<ash::DriveOperationStatus::OperationType>(
        it->operation_type);
    status.state = static_cast<ash::DriveOperationStatus::OperationState>(
        it->transfer_state);
    results.push_back(status);
  }
  return results;
}

void BluetoothPowerFailure() {
  // TODO(sad): Show an error bubble?
}

void BluetoothDiscoveryFailure() {
  // TODO(sad): Show an error bubble?
}

void BluetoothDeviceDisconnectError() {
  // TODO(sad): Do something?
}

void BluetoothSetDiscoveringError() {
  LOG(ERROR) << "BluetoothSetDiscovering failed.";
}

void BluetoothDeviceConnectError(
    device::BluetoothDevice::ConnectErrorCode error_code) {
  // TODO(sad): Do something?
}

ash::NetworkObserver::NetworkType NetworkTypeForCellular(
    const CellularNetwork* cellular) {
  if (cellular->network_technology() == NETWORK_TECHNOLOGY_LTE ||
      cellular->network_technology() == NETWORK_TECHNOLOGY_LTE_ADVANCED)
    return ash::NetworkObserver::NETWORK_CELLULAR_LTE;
  return ash::NetworkObserver::NETWORK_CELLULAR;
}

class SystemTrayDelegate : public ash::SystemTrayDelegate,
                           public AudioHandler::VolumeObserver,
                           public PowerManagerClient::Observer,
                           public SessionManagerClient::Observer,
                           public NetworkMenuIcon::Delegate,
                           public NetworkMenu::Delegate,
                           public NetworkLibrary::NetworkManagerObserver,
                           public NetworkLibrary::NetworkObserver,
                           public google_apis::DriveServiceObserver,
                           public content::NotificationObserver,
                           public input_method::InputMethodManager::Observer,
                           public system::TimezoneSettings::Observer,
                           public chromeos::SystemClockClient::Observer,
                           public device::BluetoothAdapter::Observer,
                           public SystemKeyEventListener::CapsLockObserver,
                           public ash::NetworkTrayDelegate,
                           public policy::CloudPolicyStore::Observer {
 public:
  SystemTrayDelegate()
      : ui_weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(
            new base::WeakPtrFactory<SystemTrayDelegate>(this))),
        network_icon_(ALLOW_THIS_IN_INITIALIZER_LIST(
                      new NetworkMenuIcon(this, NetworkMenuIcon::MENU_MODE))),
        network_icon_dark_(ALLOW_THIS_IN_INITIALIZER_LIST(
                      new NetworkMenuIcon(this, NetworkMenuIcon::MENU_MODE))),
        network_icon_vpn_(ALLOW_THIS_IN_INITIALIZER_LIST(
                      new NetworkMenuIcon(this, NetworkMenuIcon::MENU_MODE))),
        network_menu_(ALLOW_THIS_IN_INITIALIZER_LIST(new NetworkMenu(this))),
        clock_type_(base::k24HourClock),
        search_key_mapped_to_(input_method::kSearchKey),
        screen_locked_(false),
        have_session_start_time_(false),
        have_session_length_limit_(false),
        data_promo_notification_(new DataPromoNotification()),
        cellular_activating_(false),
        cellular_out_of_credits_(false),
        volume_control_delegate_(new VolumeController()) {
    // Register notifications on construction so that events such as
    // PROFILE_CREATED do not get missed if they happen before Initialize().
    registrar_.Add(this,
                   chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
                   content::NotificationService::AllSources());
    registrar_.Add(this,
                   chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
                   content::NotificationService::AllSources());
    if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) {
      registrar_.Add(this,
                     chrome::NOTIFICATION_SESSION_STARTED,
                     content::NotificationService::AllSources());
    }
    registrar_.Add(this,
                   chrome::NOTIFICATION_PROFILE_CREATED,
                   content::NotificationService::AllSources());
    registrar_.Add(this,
                   chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
                   content::NotificationService::AllSources());
    registrar_.Add(
        this,
        chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
        content::NotificationService::AllSources());
    registrar_.Add(
        this,
        chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
        content::NotificationService::AllSources());
    registrar_.Add(
        this,
        chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
        content::NotificationService::AllSources());
  }

  virtual void Initialize() OVERRIDE {
    AudioHandler::GetInstance()->AddVolumeObserver(this);
    DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
    DBusThreadManager::Get()->GetPowerManagerClient()->RequestStatusUpdate(
        PowerManagerClient::UPDATE_INITIAL);
    DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);

    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    crosnet->AddNetworkManagerObserver(this);
    OnNetworkManagerChanged(crosnet);

    input_method::GetInputMethodManager()->AddObserver(this);

    system::TimezoneSettings::GetInstance()->AddObserver(this);
    DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(this);

    if (SystemKeyEventListener::GetInstance())
      SystemKeyEventListener::GetInstance()->AddCapsLockObserver(this);

    network_icon_->SetResourceColorTheme(NetworkMenuIcon::COLOR_LIGHT);
    network_icon_dark_->SetResourceColorTheme(NetworkMenuIcon::COLOR_DARK);
    network_icon_vpn_->SetResourceColorTheme(NetworkMenuIcon::COLOR_DARK);

    device::BluetoothAdapterFactory::GetAdapter(
        base::Bind(&SystemTrayDelegate::InitializeOnAdapterReady,
                   ui_weak_ptr_factory_->GetWeakPtr()));
  }

  virtual void Shutdown() OVERRIDE {
    data_promo_notification_.reset();
  }

  void InitializeOnAdapterReady(
      scoped_refptr<device::BluetoothAdapter> adapter) {
    bluetooth_adapter_ = adapter;
    CHECK(bluetooth_adapter_);
    bluetooth_adapter_->AddObserver(this);

    local_state_registrar_.Init(g_browser_process->local_state());

    UpdateSessionStartTime();
    UpdateSessionLengthLimit();

    local_state_registrar_.Add(
        prefs::kSessionStartTime,
        base::Bind(&SystemTrayDelegate::UpdateSessionStartTime,
                   base::Unretained(this)));
    local_state_registrar_.Add(
        prefs::kSessionLengthLimit,
        base::Bind(&SystemTrayDelegate::UpdateSessionLengthLimit,
                   base::Unretained(this)));

    policy::BrowserPolicyConnector* policy_connector =
        g_browser_process->browser_policy_connector();
    policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
        policy_connector->GetDeviceCloudPolicyManager();
    if (policy_manager)
      policy_manager->core()->store()->AddObserver(this);
    UpdateEnterpriseDomain();
  }

  virtual ~SystemTrayDelegate() {
    AudioHandler* audiohandler = AudioHandler::GetInstance();
    if (audiohandler)
      audiohandler->RemoveVolumeObserver(this);
    DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
    DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
    DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(this);
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    if (crosnet)
      crosnet->RemoveNetworkManagerObserver(this);
    input_method::GetInputMethodManager()->RemoveObserver(this);
    system::TimezoneSettings::GetInstance()->RemoveObserver(this);
    if (SystemKeyEventListener::GetInstance())
      SystemKeyEventListener::GetInstance()->RemoveCapsLockObserver(this);
    bluetooth_adapter_->RemoveObserver(this);

    // Stop observing gdata operations.
    DriveSystemService* system_service = FindDriveSystemService();
    if (system_service) {
      system_service->drive_service()->RemoveObserver(this);
    }

    policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
        g_browser_process->browser_policy_connector()->
           GetDeviceCloudPolicyManager();
    if (policy_manager)
      policy_manager->core()->store()->RemoveObserver(this);
  }

  // Overridden from ash::SystemTrayDelegate:
  virtual bool GetTrayVisibilityOnStartup() OVERRIDE {
    // In case of OOBE / sign in screen tray will be shown later.
    return UserManager::Get()->IsUserLoggedIn();
  }

  virtual const string16 GetUserDisplayName() const OVERRIDE {
    return UserManager::Get()->GetLoggedInUser()->GetDisplayName();
  }

  virtual const std::string GetUserEmail() const OVERRIDE {
    return UserManager::Get()->GetLoggedInUser()->display_email();
  }

  virtual const gfx::ImageSkia& GetUserImage() const OVERRIDE {
    return UserManager::Get()->GetLoggedInUser()->image();
  }

  virtual ash::user::LoginStatus GetUserLoginStatus() const OVERRIDE {
    UserManager* manager = UserManager::Get();
    // At new user image screen manager->IsUserLoggedIn() would return true
    // but there's no browser session available yet so use SessionStarted().
    if (!manager->IsSessionStarted())
      return ash::user::LOGGED_IN_NONE;
    if (screen_locked_)
      return ash::user::LOGGED_IN_LOCKED;
    if (manager->IsCurrentUserOwner())
      return ash::user::LOGGED_IN_OWNER;
    if (manager->IsLoggedInAsGuest())
      return ash::user::LOGGED_IN_GUEST;
    if (manager->IsLoggedInAsDemoUser())
      return ash::user::LOGGED_IN_RETAIL_MODE;
    if (manager->IsLoggedInAsPublicAccount())
      return ash::user::LOGGED_IN_PUBLIC;
    return ash::user::LOGGED_IN_USER;
  }

  virtual bool IsOobeCompleted() const OVERRIDE {
    return WizardController::IsOobeCompleted();
  }

  virtual void ChangeProfilePicture() OVERRIDE {
    content::RecordAction(
        content::UserMetricsAction("OpenChangeProfilePictureDialog"));
    chrome::ShowSettingsSubPage(GetAppropriateBrowser(),
                                chrome::kChangeProfilePictureSubPage);
  }

  virtual const std::string GetEnterpriseDomain() const OVERRIDE {
    return enterprise_domain_;
  }

  virtual const string16 GetEnterpriseMessage() const OVERRIDE {
    if (GetEnterpriseDomain().empty())
        return string16();
    return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE,
                                      UTF8ToUTF16(GetEnterpriseDomain()));
  }

  virtual bool SystemShouldUpgrade() const OVERRIDE {
    return UpgradeDetector::GetInstance()->notify_upgrade();
  }

  virtual base::HourClockType GetHourClockType() const OVERRIDE {
    return clock_type_;
  }

  virtual PowerSupplyStatus GetPowerSupplyStatus() const OVERRIDE {
    return power_supply_status_;
  }

  virtual void RequestStatusUpdate() const OVERRIDE {
    DBusThreadManager::Get()->GetPowerManagerClient()->RequestStatusUpdate(
        PowerManagerClient::UPDATE_USER);
  }

  virtual void ShowSettings() OVERRIDE {
    chrome::ShowSettings(GetAppropriateBrowser());
  }

  virtual void ShowDateSettings() OVERRIDE {
    content::RecordAction(content::UserMetricsAction("ShowDateOptions"));
    std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
        l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME);
    chrome::ShowSettingsSubPage(GetAppropriateBrowser(), sub_page);
  }

  virtual void ShowNetworkSettings() OVERRIDE {
    content::RecordAction(
        content::UserMetricsAction("OpenInternetOptionsDialog"));
    chrome::ShowSettingsSubPage(GetAppropriateBrowser(),
                                chrome::kInternetOptionsSubPage);
  }

  virtual void ShowBluetoothSettings() OVERRIDE {
    // TODO(sad): Make this work.
  }

  virtual void ShowDisplaySettings() OVERRIDE {
    content::RecordAction(content::UserMetricsAction("ShowDisplayOptions"));
    chrome::ShowSettingsSubPage(GetAppropriateBrowser(), "display");
  }

  virtual void ShowDriveSettings() OVERRIDE {
    // TODO(hshi): Open the drive-specific settings page once we put it in.
    // For now just show search result for downoads settings.
    std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
        l10n_util::GetStringUTF8(IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME);
    chrome::ShowSettingsSubPage(GetAppropriateBrowser(), sub_page);
  }

  virtual void ShowIMESettings() OVERRIDE {
    content::RecordAction(
        content::UserMetricsAction("OpenLanguageOptionsDialog"));
    chrome::ShowSettingsSubPage(GetAppropriateBrowser(),
                                chrome::kLanguageOptionsSubPage);
  }

  virtual void ShowHelp() OVERRIDE {
    chrome::ShowHelp(GetAppropriateBrowser(), chrome::HELP_SOURCE_MENU);
  }

  virtual void ShowAccessibilityHelp() OVERRIDE {
    accessibility::ShowAccessibilityHelp(GetAppropriateBrowser());
  }

  virtual void ShowPublicAccountInfo() OVERRIDE {
    chrome::ShowPolicy(GetAppropriateBrowser());
  }

  virtual void ShowEnterpriseInfo() OVERRIDE {
    ash::user::LoginStatus status = GetUserLoginStatus();
    if (status == ash::user::LOGGED_IN_NONE ||
        status == ash::user::LOGGED_IN_LOCKED) {
      scoped_refptr<chromeos::HelpAppLauncher> help_app(
         new chromeos::HelpAppLauncher(
            GetNativeWindowByStatus(GetUserLoginStatus())));
      help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE);
    } else {
      GURL url(google_util::StringAppendGoogleLocaleParam(
          chrome::kLearnMoreEnterpriseURL));
      chrome::ShowSingletonTab(GetAppropriateBrowser(), url);
    }
  }

  virtual void ShutDown() OVERRIDE {
    ash::Shell::GetInstance()->session_state_controller()->RequestShutdown();
  }

  virtual void SignOut() OVERRIDE {
    chrome::AttemptUserExit();
  }

  virtual void RequestLockScreen() OVERRIDE {
    // TODO(antrim) : additional logging for crbug/173178
    LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate";
    DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen();
  }

  virtual void RequestRestart() OVERRIDE {
    DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
  }

  virtual void GetAvailableBluetoothDevices(
      ash::BluetoothDeviceList* list) OVERRIDE {
    device::BluetoothAdapter::DeviceList devices =
        bluetooth_adapter_->GetDevices();
    for (size_t i = 0; i < devices.size(); ++i) {
      device::BluetoothDevice* device = devices[i];
      ash::BluetoothDeviceInfo info;
      info.address = device->GetAddress();
      info.display_name = device->GetName();
      info.connected = device->IsConnected();
      info.paired = device->IsPaired();
      list->push_back(info);
    }
  }

  virtual void BluetoothStartDiscovering() OVERRIDE {
    bluetooth_adapter_->StartDiscovering(
        base::Bind(&base::DoNothing),
        base::Bind(&BluetoothSetDiscoveringError));
  }

  virtual void BluetoothStopDiscovering() OVERRIDE {
    bluetooth_adapter_->StopDiscovering(
        base::Bind(&base::DoNothing),
        base::Bind(&BluetoothSetDiscoveringError));
  }

  virtual void ToggleBluetoothConnection(const std::string& address) OVERRIDE {
    device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address);
    if (!device)
      return;
    if (device->IsConnected()) {
      device->Disconnect(
          base::Bind(&base::DoNothing),
          base::Bind(&BluetoothDeviceDisconnectError));
    } else if (device->IsPaired()) {
      device->Connect(
          NULL,
          base::Bind(&base::DoNothing),
          base::Bind(&BluetoothDeviceConnectError));
    } else {  // Show paring dialog for the unpaired device.
      BluetoothPairingDialog* dialog =
          new BluetoothPairingDialog(GetNativeWindow(), device);
      // The dialog deletes itself on close.
      dialog->Show();
    }
  }

  virtual bool IsBluetoothDiscovering() OVERRIDE {
    return bluetooth_adapter_->IsDiscovering();
  }

  virtual void GetCurrentIME(ash::IMEInfo* info) OVERRIDE {
    input_method::InputMethodManager* manager =
        input_method::GetInputMethodManager();
    input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
    input_method::InputMethodDescriptor ime = manager->GetCurrentInputMethod();
    ExtractIMEInfo(ime, *util, info);
    info->selected = true;
  }

  virtual void GetAvailableIMEList(ash::IMEInfoList* list) OVERRIDE {
    input_method::InputMethodManager* manager =
        input_method::GetInputMethodManager();
    input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
    scoped_ptr<input_method::InputMethodDescriptors> ime_descriptors(
        manager->GetActiveInputMethods());
    std::string current = manager->GetCurrentInputMethod().id();
    for (size_t i = 0; i < ime_descriptors->size(); i++) {
      input_method::InputMethodDescriptor& ime = ime_descriptors->at(i);
      ash::IMEInfo info;
      ExtractIMEInfo(ime, *util, &info);
      info.selected = ime.id() == current;
      list->push_back(info);
    }
  }

  virtual void GetCurrentIMEProperties(
      ash::IMEPropertyInfoList* list) OVERRIDE {
    input_method::InputMethodManager* manager =
        input_method::GetInputMethodManager();
    input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
    input_method::InputMethodPropertyList properties =
        manager->GetCurrentInputMethodProperties();
    for (size_t i = 0; i < properties.size(); ++i) {
      ash::IMEPropertyInfo property;
      property.key = properties[i].key;
      property.name = util->TranslateString(properties[i].label);
      property.selected = properties[i].is_selection_item_checked;
      list->push_back(property);
    }
  }

  virtual void SwitchIME(const std::string& ime_id) OVERRIDE {
    input_method::GetInputMethodManager()->ChangeInputMethod(ime_id);
  }

  virtual void ActivateIMEProperty(const std::string& key) OVERRIDE {
    input_method::GetInputMethodManager()->
        ActivateInputMethodProperty(key);
  }

  virtual void CancelDriveOperation(const base::FilePath& file_path) OVERRIDE {
    DriveSystemService* system_service = FindDriveSystemService();
    if (!system_service)
      return;

    system_service->drive_service()->CancelForFilePath(file_path);
  }

  virtual void GetDriveOperationStatusList(
      ash::DriveOperationStatusList* list) OVERRIDE {
    DriveSystemService* system_service = FindDriveSystemService();
    if (!system_service)
      return;

    *list = GetDriveStatusList(
        system_service->drive_service()->GetProgressStatusList());
  }

  virtual void GetMostRelevantNetworkIcon(ash::NetworkIconInfo* info,
                                          bool dark) OVERRIDE {
    NetworkMenuIcon* icon =
        dark ? network_icon_dark_.get() : network_icon_.get();
    info->image = icon->GetIconAndText(&info->description);
    info->tray_icon_visible = icon->ShouldShowIconInTray();
  }

  virtual void GetVirtualNetworkIcon(ash::NetworkIconInfo* info) OVERRIDE {
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    if (crosnet->virtual_network_connected()) {
      NetworkMenuIcon* icon = network_icon_vpn_.get();
      info->image = icon->GetVpnIconAndText(&info->description);
      info->tray_icon_visible = false;
    } else {
      gfx::ImageSkia* image = NetworkMenuIcon::GetVirtualNetworkImage();
      info->image = *image;
      info->description = l10n_util::GetStringUTF16(
          IDS_ASH_STATUS_TRAY_VPN_DISCONNECTED);
    }
  }

  virtual void GetAvailableNetworks(
      std::vector<ash::NetworkIconInfo>* list) OVERRIDE {
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();

    std::set<const Network*> added;

    // Add the active network first.
    if (crosnet->active_nonvirtual_network())
      AddNetworkToList(list, &added, crosnet->active_nonvirtual_network());

    if (crosnet->ethernet_network() &&
        crosnet->ethernet_network()->connecting_or_connected()) {
      AddNetworkToList(list, &added, crosnet->ethernet_network());
    }
    if (crosnet->cellular_network()
        && crosnet->cellular_network()->connecting_or_connected()) {
      AddNetworkToList(list, &added, crosnet->cellular_network());
    }
    if (crosnet->wimax_network()
        && crosnet->wimax_network()->connecting_or_connected()) {
      AddNetworkToList(list, &added, crosnet->wimax_network());
    }
    if (crosnet->wifi_network()
        && crosnet->wifi_network()->connecting_or_connected()) {
      AddNetworkToList(list, &added, crosnet->wifi_network());
    }

    // Add remaining networks by type.

    // Ethernet.
    if (crosnet->ethernet_available() && crosnet->ethernet_enabled()) {
      const EthernetNetwork* ethernet_network = crosnet->ethernet_network();
      if (ethernet_network)
        AddNetworkToList(list, &added, ethernet_network);
    }

    // Cellular.
    if (crosnet->cellular_available() && crosnet->cellular_enabled()) {
      const CellularNetworkVector& cell = crosnet->cellular_networks();
      for (size_t i = 0; i < cell.size(); ++i)
        AddNetworkToList(list, &added, cell[i]);
    }

    // Wimax.
    if (crosnet->wimax_available() && crosnet->wimax_enabled()) {
      const WimaxNetworkVector& wimax = crosnet->wimax_networks();
      for (size_t i = 0; i < wimax.size(); ++i)
        AddNetworkToList(list, &added, wimax[i]);
    }

    // Wifi.
    if (crosnet->wifi_available() && crosnet->wifi_enabled()) {
      const WifiNetworkVector& wifi = crosnet->wifi_networks();
      for (size_t i = 0; i < wifi.size(); ++i)
        AddNetworkToList(list, &added, wifi[i]);
    }
  }

  virtual void GetVirtualNetworks(
      std::vector<ash::NetworkIconInfo>* list) OVERRIDE {
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    std::set<const Network*> added;

    // Add connected/connecting vpn first.
    if (crosnet->virtual_network()
        && crosnet->virtual_network()->connecting_or_connected()) {
      AddNetworkToList(list, &added, crosnet->virtual_network());
    }

    // VPN (only if logged in).
    if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE &&
        (crosnet->connected_network() ||
         crosnet->virtual_network_connected())) {
      const VirtualNetworkVector& vpns = crosnet->virtual_networks();
      for (size_t i = 0; i < vpns.size(); ++i)
        AddNetworkToList(list, &added, vpns[i]);
    }
  }

  virtual void GetNetworkAddresses(std::string* ip_address,
                                   std::string* ethernet_mac_address,
                                   std::string* wifi_mac_address) OVERRIDE {
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    if (crosnet->Connected())
      *ip_address = crosnet->IPAddress();
    else
      *ip_address = std::string();

    *ethernet_mac_address = std::string();
    const NetworkDevice* ether = crosnet->FindEthernetDevice();
    if (ether)
      crosnet->GetIPConfigsAndBlock(ether->device_path(), ethernet_mac_address,
          NetworkLibrary::FORMAT_COLON_SEPARATED_HEX);

    *wifi_mac_address = std::string();
    const NetworkDevice* wifi = crosnet->wifi_enabled() ?
        crosnet->FindWifiDevice() : NULL;
    if (wifi)
      crosnet->GetIPConfigsAndBlock(wifi->device_path(), wifi_mac_address,
          NetworkLibrary::FORMAT_COLON_SEPARATED_HEX);
  }

  virtual void ConnectToNetwork(const std::string& network_id) OVERRIDE {
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    Network* network = crosnet->FindNetworkByPath(network_id);
    if (network)
      network_menu_->ConnectToNetwork(network);  // Shows settings if connected
    else
      ShowNetworkSettings();
  }

  virtual void RequestNetworkScan() OVERRIDE {
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    crosnet->RequestNetworkScan();
  }

  virtual void AddBluetoothDevice() OVERRIDE {
    // Open the Bluetooth device dialog, which automatically starts the
    // discovery process.
    content::RecordAction(
        content::UserMetricsAction("OpenAddBluetoothDeviceDialog"));
    chrome::ShowSettingsSubPage(GetAppropriateBrowser(),
                                chrome::kBluetoothAddDeviceSubPage);
  }

  virtual void ToggleAirplaneMode() OVERRIDE {
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    crosnet->EnableOfflineMode(!crosnet->offline_mode());
  }

  virtual void ToggleWifi() OVERRIDE {
    GetSystemTrayNotifier()->NotifyWillToggleWifi();
    network_menu_->ToggleWifi();
  }

  virtual void ToggleMobile() OVERRIDE {
    network_menu_->ToggleMobile();
  }

  virtual void ToggleBluetooth() OVERRIDE {
    bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(),
                                   base::Bind(&base::DoNothing),
                                   base::Bind(&BluetoothPowerFailure));
  }

  virtual void ShowOtherWifi() OVERRIDE {
    network_menu_->ShowOtherWifi();
  }

  virtual void ShowOtherVPN() OVERRIDE {
    network_menu_->ShowOtherVPN();
  }

  virtual void ShowOtherCellular() OVERRIDE {
    network_menu_->ShowOtherCellular();
  }

  virtual bool IsNetworkConnected() OVERRIDE {
    return CrosLibrary::Get()->GetNetworkLibrary()->Connected();
  }

  virtual bool GetWifiAvailable() OVERRIDE {
    return CrosLibrary::Get()->GetNetworkLibrary()->wifi_available();
  }

  virtual bool GetMobileAvailable() OVERRIDE {
    return CrosLibrary::Get()->GetNetworkLibrary()->mobile_available();
  }

  virtual bool GetBluetoothAvailable() OVERRIDE {
    return bluetooth_adapter_->IsPresent();
  }

  virtual bool GetWifiEnabled() OVERRIDE {
    return CrosLibrary::Get()->GetNetworkLibrary()->wifi_enabled();
  }

  virtual bool GetMobileEnabled() OVERRIDE {
    return CrosLibrary::Get()->GetNetworkLibrary()->mobile_enabled();
  }

  virtual bool GetBluetoothEnabled() OVERRIDE {
    return bluetooth_adapter_->IsPowered();
  }

  virtual bool GetMobileScanSupported() OVERRIDE {
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    const NetworkDevice* mobile = crosnet->FindMobileDevice();
    return mobile ? mobile->support_network_scan() : false;
  }

  virtual bool GetCellularCarrierInfo(std::string* carrier_id,
                                      std::string* topup_url,
                                      std::string* setup_url) OVERRIDE {
    bool result = false;
    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
    const NetworkDevice* cellular = crosnet->FindCellularDevice();
    if (!cellular)
      return false;

    MobileConfig* config = MobileConfig::GetInstance();
    if (config->IsReady()) {
      *carrier_id = crosnet->GetCellularHomeCarrierId();
      const MobileConfig::Carrier* carrier = config->GetCarrier(*carrier_id);
      if (carrier) {
        *topup_url = carrier->top_up_url();
        result = true;
      }
      const MobileConfig::LocaleConfig* locale_config =
          config->GetLocaleConfig();
      if (locale_config) {
        // Only link to setup URL if SIM card is not inserted.
        if (cellular->is_sim_absent()) {
          *setup_url = locale_config->setup_url();
          result = true;
        }
      }
    }
    return result;
  }

  virtual bool GetWifiScanning() OVERRIDE {
    return CrosLibrary::Get()->GetNetworkLibrary()->wifi_scanning();
  }

  virtual bool GetCellularInitializing() OVERRIDE {
    return CrosLibrary::Get()->GetNetworkLibrary()->cellular_initializing();
  }

  virtual void ShowCellularURL(const std::string& url) OVERRIDE {
    chrome::ShowSingletonTab(GetAppropriateBrowser(), GURL(url));
  }

  virtual void ChangeProxySettings() OVERRIDE {
    CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE);
    BaseLoginDisplayHost::default_host()->OpenProxySettings();
  }

  virtual ash::VolumeControlDelegate*
  GetVolumeControlDelegate() const OVERRIDE {
    return volume_control_delegate_.get();
  }

  virtual void SetVolumeControlDelegate(
      scoped_ptr<ash::VolumeControlDelegate> delegate) OVERRIDE {
    volume_control_delegate_.swap(delegate);
  }

  virtual bool GetSessionStartTime(
      base::TimeTicks* session_start_time) OVERRIDE {
    *session_start_time = session_start_time_;
    return have_session_start_time_;
  }

  virtual bool GetSessionLengthLimit(
      base::TimeDelta* session_length_limit) OVERRIDE {
    *session_length_limit = session_length_limit_;
    return have_session_length_limit_;
  }

  virtual int GetSystemTrayMenuWidth() OVERRIDE {
    return l10n_util::GetLocalizedContentsWidthInPixels(
        IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS);
  }

  virtual string16 FormatTimeDuration(
      const base::TimeDelta& delta) const OVERRIDE {
    return TimeFormat::TimeDurationLong(delta);
  }

  virtual void MaybeSpeak(const std::string& utterance) const OVERRIDE {
    accessibility::MaybeSpeak(utterance);
  }

 private:
  ash::SystemTray* GetPrimarySystemTray() {
    return ash::Shell::GetInstance()->GetPrimarySystemTray();
  }

  ash::SystemTrayNotifier* GetSystemTrayNotifier() {
    return ash::Shell::GetInstance()->system_tray_notifier();
  }

  // Returns the last active browser. If there is no such browser, creates a new
  // browser window with an empty tab and returns it.
  Browser* GetAppropriateBrowser() {
    return chrome::FindOrCreateTabbedBrowser(
        ProfileManager::GetDefaultProfileOrOffTheRecord(),
        chrome::HOST_DESKTOP_TYPE_ASH);
  }

  void SetProfile(Profile* profile) {
    PrefService* prefs = profile->GetPrefs();
    user_pref_registrar_.reset(new PrefChangeRegistrar);
    user_pref_registrar_->Init(prefs);
    user_pref_registrar_->Add(
        prefs::kUse24HourClock,
        base::Bind(&SystemTrayDelegate::UpdateClockType,
                   base::Unretained(this)));
    user_pref_registrar_->Add(
        prefs::kLanguageRemapSearchKeyTo,
        base::Bind(&SystemTrayDelegate::OnLanguageRemapSearchKeyToChanged,
                   base::Unretained(this)));
    user_pref_registrar_->Add(
        prefs::kShowLogoutButtonInTray,
        base::Bind(&SystemTrayDelegate::UpdateShowLogoutButtonInTray,
                   base::Unretained(this)));
    user_pref_registrar_->Add(
        prefs::kShouldAlwaysShowAccessibilityMenu,
        base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged,
                   base::Unretained(this),
                   ash::A11Y_NOTIFICATION_NONE));

    UpdateClockType();
    UpdateShowLogoutButtonInTray();
    search_key_mapped_to_ =
        profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo);
  }

  void ObserveGDataUpdates() {
    DriveSystemService* system_service = FindDriveSystemService();
    if (!system_service)
      return;

    system_service->drive_service()->AddObserver(this);
  }

  void UpdateClockType() {
    clock_type_ =
        user_pref_registrar_->prefs()->GetBoolean(prefs::kUse24HourClock) ?
            base::k24HourClock : base::k12HourClock;
    GetSystemTrayNotifier()->NotifyDateFormatChanged();
  }

  void UpdateShowLogoutButtonInTray() {
    GetSystemTrayNotifier()->NotifyShowLoginButtonChanged(
        user_pref_registrar_->prefs()->GetBoolean(
            prefs::kShowLogoutButtonInTray));
  }

  void UpdateSessionStartTime() {
    const PrefService* local_state = local_state_registrar_.prefs();
    if (local_state->HasPrefPath(prefs::kSessionStartTime)) {
      have_session_start_time_ = true;
      session_start_time_ = base::TimeTicks::FromInternalValue(
          local_state->GetInt64(prefs::kSessionStartTime));
    } else {
      have_session_start_time_ = false;
      session_start_time_ = base::TimeTicks();
    }
    GetSystemTrayNotifier()->NotifySessionStartTimeChanged();
  }

  void UpdateSessionLengthLimit() {
    const PrefService* local_state = local_state_registrar_.prefs();
    if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) {
      have_session_length_limit_ = true;
      session_length_limit_ = base::TimeDelta::FromMilliseconds(
          std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit),
                            kSessionLengthLimitMinMs),
                   kSessionLengthLimitMaxMs));
    } else {
      have_session_length_limit_ = false;
      session_length_limit_ = base::TimeDelta();
    }
    GetSystemTrayNotifier()->NotifySessionLengthLimitChanged();
  }

  void NotifyRefreshNetwork() {
    chromeos::NetworkLibrary* crosnet =
        chromeos::CrosLibrary::Get()->GetNetworkLibrary();
    const Network* network = crosnet->connected_network();
    ash::NetworkIconInfo info;
    if (network)
      info = CreateNetworkIconInfo(network);
    info.image = network_icon_->GetIconAndText(&info.description);
    info.tray_icon_visible = network_icon_->ShouldShowIconInTray();
    GetSystemTrayNotifier()->NotifyRefreshNetwork(info);
    GetSystemTrayNotifier()->NotifyVpnRefreshNetwork(info);
  }

  void RefreshNetworkObserver(NetworkLibrary* crosnet) {
    const Network* network = crosnet->active_nonvirtual_network();
    std::string new_path = network ? network->service_path() : std::string();
    if (active_network_path_ != new_path) {
      if (!active_network_path_.empty())
        crosnet->RemoveNetworkObserver(active_network_path_, this);
      if (!new_path.empty())
        crosnet->AddNetworkObserver(new_path, this);
      active_network_path_ = new_path;
    }
  }

  void AddNetworkToList(std::vector<ash::NetworkIconInfo>* list,
                        std::set<const Network*>* added,
                        const Network* network) {
    // Only add networks to the list once.
    if (added->find(network) != added->end())
      return;

    ash::NetworkIconInfo info = CreateNetworkIconInfo(network);
    switch (network->type()) {
      case TYPE_ETHERNET:
        if (info.name.empty()) {
          info.name =
              l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
        }
        break;
      case TYPE_CELLULAR: {
        const CellularNetwork* cellular =
            static_cast<const CellularNetwork*>(network);
        ActivationState state = cellular->activation_state();
        if (state == ACTIVATION_STATE_NOT_ACTIVATED ||
            state == ACTIVATION_STATE_PARTIALLY_ACTIVATED) {
          // If a cellular network needs to be activated,
          // then do not show it in the lock screen.
          if (GetUserLoginStatus() == ash::user::LOGGED_IN_LOCKED)
            return;

          info.description = l10n_util::GetStringFUTF16(
              IDS_ASH_STATUS_TRAY_NETWORK_LIST_ACTIVATE, info.name);
        } else if (state == ACTIVATION_STATE_ACTIVATING) {
          info.description = l10n_util::GetStringFUTF16(
              IDS_ASH_STATUS_TRAY_NETWORK_LIST_ACTIVATING, info.name);
        } else if (network->connecting()) {
          info.description = l10n_util::GetStringFUTF16(
              IDS_STATUSBAR_NETWORK_DEVICE_STATUS,
              info.name, l10n_util::GetStringUTF16(
                  IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING));
        }
        break;
      }
      case TYPE_VPN:
      case TYPE_WIFI:
      case TYPE_WIMAX:
      case TYPE_BLUETOOTH:
      case TYPE_UNKNOWN:
        break;
    }
    if (network->connecting()) {
      info.description = l10n_util::GetStringFUTF16(
          IDS_STATUSBAR_NETWORK_DEVICE_STATUS,
          info.name,
          l10n_util::GetStringUTF16(
              IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING));
    }
    added->insert(network);
    list->push_back(info);
  }

  // Overridden from AudioHandler::VolumeObserver.
  virtual void OnVolumeChanged() OVERRIDE {
    float level = AudioHandler::GetInstance()->GetVolumePercent() / 100.f;
    GetSystemTrayNotifier()->NotifyVolumeChanged(level);
  }

  // Overridden from AudioHandler::VolumeObserver.
  virtual void OnMuteToggled() OVERRIDE {
    GetSystemTrayNotifier()->NotifyMuteToggled();
  }

  // Overridden from PowerManagerClient::Observer.
  virtual void BrightnessChanged(int level, bool user_initiated) OVERRIDE {
    double leveld = static_cast<double>(level);
    GetSystemTrayNotifier()->NotifyBrightnessChanged(leveld, user_initiated);
  }

  virtual void PowerChanged(const PowerSupplyStatus& power_status) OVERRIDE {
    power_supply_status_ = power_status;
    GetSystemTrayNotifier()->NotifyPowerStatusChanged(power_status);
  }

  // Overridden from PowerManagerClient::Observer:
  virtual void SystemResumed(const base::TimeDelta& sleep_duration) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshClock();
  }

  // Overridden from SessionManagerClient::Observer.
  virtual void LockScreen() OVERRIDE {
    screen_locked_ = true;
    ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
        GetUserLoginStatus());
  }

  virtual void UnlockScreen() OVERRIDE {
    screen_locked_ = false;
    ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
        GetUserLoginStatus());
  }

  // TODO(sad): Override more from PowerManagerClient::Observer here.

  // Overridden from NetworkMenuIcon::Delegate.
  virtual void NetworkMenuIconChanged() OVERRIDE {
    NotifyRefreshNetwork();
  }

  // Overridden from NetworkMenu::Delegate.
  virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE {
    return GetNativeWindowByStatus(GetUserLoginStatus());
  }

  virtual void OpenButtonOptions() OVERRIDE {
  }

  virtual bool ShouldOpenButtonOptions() const OVERRIDE {
    return false;
  }

  // Overridden from NetworkLibrary::NetworkManagerObserver.
  virtual void OnNetworkManagerChanged(NetworkLibrary* crosnet) OVERRIDE {
    RefreshNetworkObserver(crosnet);
    data_promo_notification_->ShowOptionalMobileDataPromoNotification(
        crosnet, GetPrimarySystemTray(), this);
    UpdateCellular();

    NotifyRefreshNetwork();
  }

  // Overridden from NetworkLibrary::NetworkObserver.
  virtual void OnNetworkChanged(NetworkLibrary* crosnet,
      const Network* network) OVERRIDE {
    NotifyRefreshNetwork();
  }

  // content::NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE {
    switch (type) {
      case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
        UpgradeDetector* detector =
            content::Source<UpgradeDetector>(source).ptr();
        ash::UpdateObserver::UpdateSeverity severity =
            ash::UpdateObserver::UPDATE_NORMAL;
        switch (detector->upgrade_notification_stage()) {
          case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE:
            severity = ash::UpdateObserver::UPDATE_SEVERE_RED;
            break;

          case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH:
            severity = ash::UpdateObserver::UPDATE_HIGH_ORANGE;
            break;

          case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED:
            severity = ash::UpdateObserver::UPDATE_LOW_GREEN;
            break;

          case UpgradeDetector::UPGRADE_ANNOYANCE_LOW:
          default:
            severity = ash::UpdateObserver::UPDATE_NORMAL;
            break;
        }
        GetSystemTrayNotifier()->NotifyUpdateRecommended(severity);
        break;
      }
      case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
        // This notification is also sent on login screen when user avatar
        // is loaded from file.
        if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) {
          GetSystemTrayNotifier()->NotifyUserUpdate();
        }
        break;
      }
      case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
        // GData system service exists by the time if enabled.
        ObserveGDataUpdates();
        break;
      }
      case chrome::NOTIFICATION_PROFILE_CREATED: {
        SetProfile(content::Source<Profile>(source).ptr());
        registrar_.Remove(this,
                          chrome::NOTIFICATION_PROFILE_CREATED,
                          content::NotificationService::AllSources());
        break;
      }
      case chrome::NOTIFICATION_SESSION_STARTED: {
        ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(
            GetUserLoginStatus());
        SetProfile(ProfileManager::GetDefaultProfile());
        break;
      }
      case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK:
      case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE:
      case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER: {
        accessibility::AccessibilityStatusEventDetails* accessibility_status =
            content::Details<accessibility::AccessibilityStatusEventDetails>(
                details).ptr();
        OnAccessibilityModeChanged(accessibility_status->notify);
        break;
      }
      default:
        NOTREACHED();
    }
  }

  void OnLanguageRemapSearchKeyToChanged() {
    search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger(
        prefs::kLanguageRemapSearchKeyTo);
  }

  void OnAccessibilityModeChanged(
      ash::AccessibilityNotificationVisibility notify) {
    GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify);
  }

  // Overridden from InputMethodManager::Observer.
  virtual void InputMethodChanged(
      input_method::InputMethodManager* manager, bool show_message) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshIME(show_message);
  }

  virtual void InputMethodPropertyChanged(
      input_method::InputMethodManager* manager) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshIME(false);
  }

  // google_apis::DriveServiceObserver overrides.
  virtual void OnProgressUpdate(
      const google_apis::OperationProgressStatusList& list) OVERRIDE {
    std::vector<ash::DriveOperationStatus> ui_list = GetDriveStatusList(list);
    GetSystemTrayNotifier()->NotifyRefreshDrive(ui_list);

    // If we have something to report right now (i.e. completion status only),
    // we need to delayed re-check the status in few seconds to ensure we
    // raise events that will let us properly clear the uber tray state.
    if (list.size() > 0) {
      bool has_in_progress_items = false;
      for (google_apis::OperationProgressStatusList::const_iterator it =
               list.begin();
           it != list.end(); ++it) {
        if (it->transfer_state == google_apis::OPERATION_STARTED ||
            it->transfer_state == google_apis::OPERATION_IN_PROGRESS ||
            it->transfer_state == google_apis::OPERATION_SUSPENDED) {
          has_in_progress_items = true;
          break;
        }
      }

      if (!has_in_progress_items) {
        content::BrowserThread::PostDelayedTask(
            content::BrowserThread::UI,
            FROM_HERE,
            base::Bind(&SystemTrayDelegate::RecheckGDataOperations,
                       ui_weak_ptr_factory_->GetWeakPtr()),
            base::TimeDelta::FromMilliseconds(kGDataOperationRecheckDelayMs));
      }
    }
  }

  // Pulls the list of ongoing drive operations and initiates status update.
  // This method is needed to ensure delayed cleanup of the latest reported
  // status in UI in cases when there are no new changes coming (i.e. when the
  // last set of transfer operations completed).
  void RecheckGDataOperations() {
    DriveSystemService* system_service = FindDriveSystemService();
    if (!system_service)
      return;

    OnProgressUpdate(system_service->drive_service()->GetProgressStatusList());
  }

  DriveSystemService* FindDriveSystemService() {
    Profile* profile = ProfileManager::GetDefaultProfile();
    return DriveSystemServiceFactory::FindForProfile(profile);
  }

  // Overridden from system::TimezoneSettings::Observer.
  virtual void TimezoneChanged(const icu::TimeZone& timezone) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshClock();
  }

  // Overridden from SystemClockClient::Observer.
  virtual void SystemClockUpdated() OVERRIDE {
    GetSystemTrayNotifier()->NotifySystemClockTimeUpdated();
  }

  // Overridden from BluetoothAdapter::Observer.
  virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
                                     bool present) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshBluetooth();
  }

  virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
                                     bool powered) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshBluetooth();
  }

  virtual void AdapterDiscoveringChanged(device::BluetoothAdapter* adapter,
                                         bool discovering) OVERRIDE {
    GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged();
  }

  virtual void DeviceAdded(device::BluetoothAdapter* adapter,
                           device::BluetoothDevice* device) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshBluetooth();
  }

  virtual void DeviceChanged(device::BluetoothAdapter* adapter,
                             device::BluetoothDevice* device) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshBluetooth();
  }

  virtual void DeviceRemoved(device::BluetoothAdapter* adapter,
                             device::BluetoothDevice* device) OVERRIDE {
    GetSystemTrayNotifier()->NotifyRefreshBluetooth();
  }

  // Overridden from SystemKeyEventListener::CapsLockObserver.
  virtual void OnCapsLockChange(bool enabled) OVERRIDE {
    bool search_mapped_to_caps_lock = false;
    if (!base::chromeos::IsRunningOnChromeOS() ||
        search_key_mapped_to_ == input_method::kCapsLockKey)
      search_mapped_to_caps_lock = true;
    GetSystemTrayNotifier()->NotifyCapsLockChanged(
        enabled, search_mapped_to_caps_lock);
  }

  // Overridden from ash::NetworkTrayDelegate
  virtual void NotificationLinkClicked(
      ash::NetworkObserver::MessageType message_type,
      size_t link_index) OVERRIDE {
    if (message_type == ash::NetworkObserver::ERROR_OUT_OF_CREDITS) {
      const CellularNetwork* cellular =
          CrosLibrary::Get()->GetNetworkLibrary()->cellular_network();
      if (cellular)
        ConnectToNetwork(cellular->service_path());
      ash::Shell::GetInstance()->system_tray_notifier()->
          NotifyClearNetworkMessage(message_type);
    }
    if (message_type != ash::NetworkObserver::MESSAGE_DATA_PROMO)
      return;
    // If we have deal info URL defined that means that there're
    // 2 links in bubble. Let the user close it manually then thus giving
    // ability to navigate to second link.
    // mobile_data_bubble_ will be set to NULL in BubbleClosing callback.
    std::string deal_info_url = data_promo_notification_->deal_info_url();
    std::string deal_topup_url = data_promo_notification_->deal_topup_url();
    if (deal_info_url.empty())
      data_promo_notification_->CloseNotification();

    std::string deal_url_to_open;
    if (link_index == 0) {
      if (!deal_topup_url.empty()) {
        deal_url_to_open = deal_topup_url;
      } else {
        const Network* cellular =
            CrosLibrary::Get()->GetNetworkLibrary()->cellular_network();
        if (!cellular)
          return;
        network_menu_->ShowTabbedNetworkSettings(cellular);
        return;
      }
    } else if (link_index == 1) {
      deal_url_to_open = deal_info_url;
    }

    if (!deal_url_to_open.empty()) {
      Browser* browser = GetAppropriateBrowser();
      if (!browser)
        return;
      chrome::ShowSingletonTab(browser, GURL(deal_url_to_open));
    }
  }

  virtual void UpdateEnterpriseDomain() {
    std::string enterprise_domain =
        g_browser_process->browser_policy_connector()->GetEnterpriseDomain();
    if (enterprise_domain_ != enterprise_domain) {
       enterprise_domain_ = enterprise_domain;
       GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged();
    }
  }

  // Overridden from CloudPolicyStore::Observer
  virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE {
    UpdateEnterpriseDomain();
  }

  virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE {
    UpdateEnterpriseDomain();
  }

  void UpdateCellular() {
    const CellularNetworkVector& cellular_networks =
        CrosLibrary::Get()->GetNetworkLibrary()->cellular_networks();
    if (cellular_networks.empty())
      return;
    // We only care about the first cellular network (in practice there will
    // only ever be one)
    const CellularNetwork* cellular = cellular_networks[0];
    if (cellular->activation_state() == ACTIVATION_STATE_ACTIVATING) {
      cellular_activating_ = true;
    } else if (cellular->activated() && cellular_activating_) {
      cellular_activating_ = false;
      ash::NetworkObserver::NetworkType type = NetworkTypeForCellular(cellular);
      ash::Shell::GetInstance()->system_tray_notifier()->
          NotifySetNetworkMessage(
              NULL,
              ash::NetworkObserver::MESSAGE_DATA_PROMO,
              type,
              l10n_util::GetStringUTF16(
                  IDS_NETWORK_CELLULAR_ACTIVATED_TITLE),
              l10n_util::GetStringFUTF16(
                  IDS_NETWORK_CELLULAR_ACTIVATED,
                  UTF8ToUTF16((cellular->name()))),
                  std::vector<string16>());
    }
    if (!CommandLine::ForCurrentProcess()->HasSwitch(
            ash::switches::kAshDisableNewNetworkStatusArea)) {
      return;
    }
    // Trigger "Out of credits" notification (for NetworkLibrary impl)
    if (cellular->out_of_credits() && !cellular_out_of_credits_) {
      cellular_out_of_credits_ = true;
      ash::NetworkObserver::NetworkType type = NetworkTypeForCellular(cellular);
      std::vector<string16> links;
      links.push_back(
          l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_CREDITS_LINK,
                                     UTF8ToUTF16(cellular->name())));
      ash::Shell::GetInstance()->system_tray_notifier()->
          NotifySetNetworkMessage(
              this, ash::NetworkObserver::ERROR_OUT_OF_CREDITS, type,
              l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE),
              l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_BODY),
              links);
    } else if (!cellular->out_of_credits() && cellular_out_of_credits_) {
      cellular_out_of_credits_ = false;
    }
  }

  scoped_ptr<base::WeakPtrFactory<SystemTrayDelegate> > ui_weak_ptr_factory_;
  scoped_ptr<NetworkMenuIcon> network_icon_;
  scoped_ptr<NetworkMenuIcon> network_icon_dark_;
  scoped_ptr<NetworkMenuIcon> network_icon_vpn_;
  scoped_ptr<NetworkMenu> network_menu_;
  content::NotificationRegistrar registrar_;
  PrefChangeRegistrar local_state_registrar_;
  scoped_ptr<PrefChangeRegistrar> user_pref_registrar_;
  std::string active_network_path_;
  PowerSupplyStatus power_supply_status_;
  base::HourClockType clock_type_;
  int search_key_mapped_to_;
  bool screen_locked_;
  bool have_session_start_time_;
  base::TimeTicks session_start_time_;
  bool have_session_length_limit_;
  base::TimeDelta session_length_limit_;
  std::string enterprise_domain_;

  scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;

  scoped_ptr<DataPromoNotification> data_promo_notification_;
  bool cellular_activating_;
  bool cellular_out_of_credits_;

  scoped_ptr<ash::VolumeControlDelegate> volume_control_delegate_;

  DISALLOW_COPY_AND_ASSIGN(SystemTrayDelegate);
};

}  // namespace

ash::SystemTrayDelegate* CreateSystemTrayDelegate() {
  return new chromeos::SystemTrayDelegate();
}

}  // namespace chromeos


text:
export * from './collection-page.component';
export * from './find-book-page.component';
export * from './selected-book-page.component';
export * from './view-book-page.component';

redpajama_set_name: RedPajamaGithub


text:
package knorxx.framework.generator.dependency;

import com.google.common.collect.Sets;
import java.util.Set;
import knorxx.framework.generator.BaseGeneratorTestWithMultipleClassLoader;
import knorxx.framework.generator.JavaFileOnClasspath;
import knorxx.framework.generator.dependency.testclass.bytecode.AnonymousInnerClass;
import knorxx.framework.generator.dependency.testclass.bytecode.AnonymousInnerClassWithStaticHelperInSamePackage;
import knorxx.framework.generator.dependency.testclass.bytecode.DependencyWithInnerClass;
import knorxx.framework.generator.dependency.testclass.bytecode.Enumeration;
import knorxx.framework.generator.dependency.testclass.bytecode.InnerClass;
import knorxx.framework.generator.dependency.testclass.bytecode.NestedInnerClasses;
import knorxx.framework.generator.dependency.testclass.bytecode.NestedStaticInnerClasses;
import knorxx.framework.generator.dependency.testclass.bytecode.Simple;
import knorxx.framework.generator.dependency.testclass.bytecode.StaticHelperClass;
import knorxx.framework.generator.dependency.testclass.bytecode.StaticInnerClass;
import static org.hamcrest.core.IsCollectionContaining.hasItems;
import static org.junit.Assert.assertThat;
import org.junit.Test;

/**
 *
 * @author sj
 */
public class ByteCodeDependencyCollectorTest extends BaseGeneratorTestWithMultipleClassLoader {

    public ByteCodeDependencyCollectorTest(ClassLoader currentClassLoader) {
        super(currentClassLoader);
    }

    @Test
    public void simple() {
        test(Simple.class, Sets.newHashSet("java.awt.Color"));
    }

    @Test
    public void innerClass() {
        test(InnerClass.class, Sets.newHashSet("java.awt.Color", "java.awt.Rectangle"));
    }

    @Test
    public void staticInnerClass() {
        test(StaticInnerClass.class, Sets.newHashSet("java.awt.Color", "java.awt.Rectangle"));
    }

    @Test
    public void nestedStaticInnerClasses() {
        test(NestedStaticInnerClasses.class, Sets.newHashSet("java.awt.Color", "java.awt.Rectangle",
                "java.awt.Point"));
    }

    @Test
    public void nestedInnerClasses() {
        test(NestedInnerClasses.class, Sets.newHashSet("java.awt.Color", "java.awt.Rectangle",
                "java.awt.Point"));
    }

    @Test
    public void anonymousInnerClass() {
        test(AnonymousInnerClass.class, Sets.newHashSet("java.awt.Rectangle"));
    }

    @Test
    public void anonymousInnerClassWithStaticHelperInSamePackage() {
        test(AnonymousInnerClassWithStaticHelperInSamePackage.class, Sets.newHashSet(StaticHelperClass.class.getName()));
    }

    @Test
    public void dependencyWithInnerClass() {
        test(DependencyWithInnerClass.class, Sets.newHashSet("com.projetloki.genesis.Properties"));
    }

	@Test
    public void enumeration() {
		test(Enumeration.class, Sets.newHashSet("java.net.StandardProtocolFamily"));
	}

    private <T> void test(Class<T> javaClass, Set<String> expectedDependencies) {
        ByteCodeDependencyCollector dependencyCollector = new ByteCodeDependencyCollector();
        Set<String> dependencies = dependencyCollector.collect(new JavaFileOnClasspath<>(javaClass), getCurrentClassLoader());

        assertThat(dependencies, hasItems(expectedDependencies.toArray(new String[]{})));
    }
}


text:
A Google Cloud Project is required in order to run the tests in the Cloud Run Samples. The project should have the following API's enabled:

* Cloud Run
* Cloud Build
* Pub/Sub
* Container Registry
* Secret Manager

## Test Project Setup

The [test-project-setup.sh](./test-project-setup.sh) script will set up a project with the appropriate permissions to run the tests. To run the script you will need to set the following environment variables locally:

* TEAM_FOLDER [optional]
  * The numeric ID of the [folder][folder]
  * Note: TEAM_FOLDER is optional for the script, but may be required by your organization policy.

* PROJECT_SUFFIX [required]
  * Number to be attached at the end of the PROJECT_ID in order to create a unique project id.
  * Eg: 2

Once basic project setup is in place, Cloud Build must be given access to deploy Cloud Run services (see [Deploying to Cloud Run][access]).

Lastly, the Cloud Build GitHub App needs to be installed and connected to the repository. More info can be found in [Installing the Cloud Build app][app].

### Billing

The script checks your current active project to obtain the Billing Account, in order to enable the API's. This account is then linked to the new testing project.

If your current project does not have a billing account enabled, it will force the program to exit. To select a project to use for your billing account, run `gcloud config set project {PROJECT_ID}`.

## Cloud Build Templates

Cloud Build templates for Cloud Run E2E testing can be found in the
`cloudbuild-templates/` directory.

* [User-defined substitutions][sub], such as `_SAMPLE` and `_SERVICE`.

* Add integration tests, see examples below:

  * Using a shell script:

    ```yaml
    - id: 'Integration Tests'
      name: 'gcr.io/cloud-builders/curl'
      entrypoint: '/bin/sh'
      dir: $_SAMPLE
      args:
      - '-c'
      - |
        SERVICE_URL=$(cat _service_url) sh integration-tests.sh
    ```

  * Language specific testing:

    ```yaml
    - id: 'Integration Tests'
      name: 'maven:3-openjdk-11'
      entrypoint: '/bin/bash'
      dir: $_SAMPLE
      args:
      - '-c'
      - |
        SERVICE_URL=$(cat _service_url) mvn verify
    ```

**Note:** The build steps for getting the Cloud Run URL and IP are used to
export environment variables into the test runner.

### Testing private services in Cloud Run (fully managed)

Cloud Run services are deployed privately as a best practice: humans choose to make a service public, not the CI system. Cloud Run is deployed with the `--no-allow-unauthenticated` flag
to keep it private. To send HTTPS requests to the Cloud Run service, an identity token is required for [an account with the Cloud Run invoker permission](https://cloud.google.com/run/docs/authenticating/service-to-service).

To mint identity tokens on Cloud Build, load an alternate service identity with this permision in the 'Get Cloud Run URL' build step:

```sh
gcloud secrets versions access latest --secret ${_SECRET_NAME} > _sa_key.json
account=$(gcloud config get-value account)
gcloud auth activate-service-account ${_RUNNER_IDENTITY} \
  --key-file _sa_key.json --project ${PROJECT_ID}
gcloud auth print-identity-token --audiences "$(cat _service_url)" > _id_token
gcloud config set account ${account}
rm _sa_key.json
```

This secret is populated by a separate key rotation process, such as:

```sh
export SERVICE_ACCOUNT="test-runner-identity"
gcloud iam services-accounts keys create "${SERVICE_ACCOUNT}-key.json" \
  --iam-account "${SERVICE_ACCOUNT}@${TESTING_PROJECT}.iam.gserviceaccount.com"
gcloud secrets versions add ${SECRET_NAME} --data-file "${SERVICE_ACCOUNT}-key.json"
rm $SERVICE_ACCOUNT-key.json
```

Once done, any previous key should be revoked.

## Cloud Build Triggers

Each sample with tests requires two Cloud Build triggers:

* A **Pull Request trigger** which checks incoming changes.
* A **Nightly trigger** which checks the affects of product changes, environment changes, and flakiness.

These triggers are created using trigger configuration files.

1. Create the sample Pull Request trigger config (`pr.trigger-config.yaml`):

   ```yaml
   name: SAMPLE-pr
   description: pull-request
   github:
     name: cloud-run-samples
     owner: GoogleCloudPlatform
     pullRequest:
       branch: ^main$
       commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY
   includedFiles:
   - SAMPLE_DIR/**
   filename: SAMPLE_DIR/cloudbuild.yaml
   ```

1. Create the sample Nightly trigger config (`nightly.trigger-config.yaml`):

   Our nightly testing uses "manual" Cloud Build triggers. The Cloud Build Trigger UI is currently the only way to create manual triggers. A current work around is creating a "Push to branch" event trigger. This can be manually triggered and can be updated via the UI to be a "Manually run" trigger.

   ```yaml
   name: SAMPLE-nightly
   description: nightly
   github:
     name: cloud-run-samples
     owner: GoogleCloudPlatform
     push: # TODO: Update when manual triggers are supported
       branch: nightly
   includedFiles:
   - SAMPLE_DIR/**
   filename: SAMPLE_DIR/cloudbuild.yaml
   ```

1. Create a Cloud Build trigger using a config file:

   ```sh
   gcloud beta builds triggers create github \
     --trigger-config=sample/path/pr.trigger-config.yaml
   gcloud beta builds triggers create github \
     --trigger-config=sample/path/nightly.trigger-config.yaml
   ```

## Manually Start Cloud Builds

To manually trigger a Cloud Run (fully managed) build via CLI:

```sh
$SAMPLE=sample-name
gcloud builds submit \
  --config "$SAMPLE/tests.cloudbuild.yaml" \
  --substitutions "SHORT_SHA=manual,_SAMPLE_DIR=${SAMPLE},_SECRET_NAME=${SECRET_NAME},_RUNNER_IDENTITY=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"
```

We run from base directory of the repository for access to the common.sh script.

To manually trigger a Cloud Run for Anthos build via CLI:

```sh
cd $SAMPLE
gcloud builds submit --substitutions 'SHORT_SHA=manual,_SAMPLE_DIR=.'
```

[folder]: https://cloud.google.com/sdk/gcloud/reference/projects/create#--folder
[access]: https://cloud.google.com/cloud-build/docs/deploying-builds/deploy-cloud-run
[app]: https://cloud.google.com/cloud-build/docs/automating-builds/create-github-app-triggers#installing_the_cloud_build_app
[sub]: https://cloud.google.com/cloud-build/docs/configuring-builds/substitute-variable-values#using_user-defined_substitutions


text:
namespace MonoRpg.Engine.GameStates {
    using Microsoft.Xna.Framework;

    using MonoRpg.Engine.RenderEngine;
    using MonoRpg.Engine.UI;

    public class FadeState : BaseStateObject {
        public float Duration { get; set; }
        public float AlphaFinish { get; set; }
        public float AlphaStart { get; set; }
        public Color Color { get; set; }
        public Tween Tween { get; private set; }

        public FadeState(StateStack stack, FadeArgs args=null): base(stack) {
            args = args ?? new FadeArgs();
            AlphaStart = args.AlphaStart;
            AlphaFinish = args.AlphaFinish;
            Duration = args.Duration;
            Color = args.Color;
            Tween = new Tween(AlphaStart, AlphaFinish, Duration);
        }

        public override bool Update(float dt) {
            Tween.Update(dt);
            var alpha = Tween.Value;
            Color = new Color(Color, alpha);

            if (Tween.Finished) {
                Stack.Pop();
            }
            return true;
        }

        public override void Render(Renderer renderer) {
            renderer.DrawRect2D(System.Screen.Bounds, Color);
        }
    }

    public class FadeArgs {
        public float AlphaStart { get; set; }
        public float AlphaFinish { get; set; }
        public float Duration { get; set; }
        public Color Color { get; set; }

        public FadeArgs() {
            AlphaStart = 1f;
            AlphaFinish = 0f;
            Duration = 1f;
            Color = new Color(0,0,0, AlphaStart);
        }
    }
}


text:
muhser.js
======
[![NPM Version](https://img.shields.io/npm/v/musher.svg?style=flat)](https://www.npmjs.org/package/musher)
[![Build Status](http://img.shields.io/travis/taoyuan/musher.js.svg?style=flat)](https://travis-ci.org/taoyuan/musher.js)
[![Dependencies](https://img.shields.io/david/taoyuan/musher.js.svg?style=flat)](https://david-dm.org/taoyuan/musher.js)

Musher is a javascript and node.js library based on mqtt.

## Build
```bash
npm install
grunt
```

## Usage

### Subscribe with a handler.

```js
var musher = require('../');

var socket = musher.connect({host: 'localhost'});

socket.on('connected', function () {
    console.log('connected');
});
socket.on('reconnect', function () {
    console.log('reconnect');
});
socket.on('offline', function () {
    console.log('offline');
});
socket.on('error', function (err) {
    console.error(err);
});

socket.subscribe('/users/:userid/message/:messageid/*', function (data, route) {
    console.log(data);            // { hello: 'world' }
    console.log(route.topic);     // '/users/ty/message/4321/ping'
    console.log(route.params);    // { userid: 'ty', messageid: 4321 }
    console.log(route.splats);    // [ 'ping' ]
    console.log(route.path);      // '/users/:userid/message/:messageid/:method'
    console.log(route.event);     // 'message'
});

socket.publish('/users/ty/message/4321/ping', {hello: 'world'});
```

### Subscribe with event.

```js
var musher = require('../');

var socket = musher.connect({host: 'localhost'});

socket.on('connected', function () {
    console.log('connected');
});
socket.on('reconnect', function () {
    console.log('reconnect');
});
socket.on('offline', function () {
    console.log('offline');
});
socket.on('error', function (err) {
    console.error(err);
});

var channel = socket.subscribe('/users/:userid/message/:messageid/*');
channel.on('data', function (data, route) {
    console.log(data);            // { hello: 'world' }
    console.log(route.topic);     // '/users/ty/message/4321/ping'
    console.log(route.params);    // { userid: 'ty', messageid: 4321 }
    console.log(route.splats);    // [ 'ping' ]
    console.log(route.path);      // '/users/:userid/message/:messageid/:method'
    console.log(route.event);     // 'data'
});

socket.publish('/users/ty/message/4321/ping', 'data', {hello: 'world'});

```

The built libraries will be in `build` directory


text:
TOOLS_PATH=/opt/chipster/tools

#a5_miseq (päällekkäisiä työkaluja)
#PATH

#bedtools
BIN_PATH=bedtools/bin

export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#blast
BIN_PATH=blast/bin
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#bowtie
BIN_PATH=bowtie
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#bowtie2
BIN_PATH=bowtie2
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#bwa
BIN_PATH=bwa
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#ClusterBuster
BIN_PATH=ClusterBuster
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#cufflinks
BIN_PATH=cufflinks
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#cufflinks2
BIN_PATH=cufflinks2
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#dexseq-exoncounts
DEXSEQ_PATH=$TOOLS_PATH/dexseq-exoncounts
alias dexseq_count='python $DEXSEQ_PATH/dexseq_count.py'

#dimont
DIMONT_PATH=$TOOLS_PATH/dimont
alias dimont='java -jar $DIMONT_PATH/dimond'

#edirect
BIN_PATH=edirect
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#emboss
BIN_PATH=emboss/bin
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#express
BIN_PATH=express
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#FastQC
BIN_PATH=FastQC
export PATH=${PATH}::$TOOLS_PATH/$BIN_PATH

#fastx
# on /usr/bin

#fseq
BIN_PATH=fseq/bin
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#fseq_bff

#GenomeAnalysisTK2
GATK2_PATH=$TOOLS_PATH/GenomeAnalysisTK2
alias gatk='java -jar $GATK2_PATH/GenomeAnalysisTKLite.jar'

#genomes
GENOMES_FASTA=$TOOLS_PATH/genomes/fasta
GENOMES_GTF=$TOOLS_PATH/genomes/fasta
GENOMES_BOWTIE=$TOOLS_PATH/genomes/indexes/bowtie
GENOMES_BOWTIE2=$TOOLS_PATH/genomes/indexes/bowtie2
GENOMES_BWA=$TOOLS_PATH/genomes/indexes/bwa
GENOMES_TOPHAT=$TOOLS_PATH/genomes/indexes/tophat

#htseq
# on /usr/local/bin

#macs
# on /usr/local/bin

#mafft
BIN_PATH=mafft/bin
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#meme
BIN_PATH=meme/bin
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#miRNA_mappings

#mothur
BIN_PATH=mothur
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#mothur-data

#picard-tools

#primer3
BIN_PATH=primer3/src/
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#prinseq
BIN_PATH=prinseq
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#QDNAseq

#R
BIN_PATH=R-3.1.2/bin
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#RSeQC
#samtools
BIN_PATH=samtools
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#seqtk
BIN_PATH=seqtk
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#sratoolkit
BIN_PATH=sratoolkit/bin
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#tabix
BIN_PATH=tabix
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#tagcleaner
TC_PATH=$TOOLS_PATH/tagcleaner
alias tagcleaner='perl $TC_PATH/tagcleaner.pl'

#tophat
BIN_PATH=tophat
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH

#tophat2
BIN_PATH=tophat2
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH
#trimmomatic
TRIMMOMATIC_PATH=$TOOLS_PATH/trimmomatic
alias trimmomatic='java -jar $TRIMMOMATIC_PATH/trimmomatic-0.32.ja'

#vcftools
BIN_PATH=vcftools/bin
export PATH=${PATH}:$TOOLS_PATH/$BIN_PATH


text:
/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */
/* @author Arturas Paleicikas <arturas@avalon.lt> */
( function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define( [ "../widgets/datepicker" ], factory );
	} else {

		// Browser globals
		factory( jQuery.datepicker );
	}
}( function( datepicker ) {

datepicker.regional.lt = {
	closeText: "Uždaryti",
	prevText: "<Atgal",
	nextText: "Pirmyn>",
	currentText: "Šiandien",
	monthNames: [ "Sausis","Vasaris","Kovas","Balandis","Gegužė","Birželis",
	"Liepa","Rugpjūtis","Rugsėjis","Spalis","Lapkritis","Gruodis" ],
	monthNamesShort: [ "Sau","Vas","Kov","Bal","Geg","Bir",
	"Lie","Rugp","Rugs","Spa","Lap","Gru" ],
	dayNames: [
		"sekmadienis",
		"pirmadienis",
		"antradienis",
		"trečiadienis",
		"ketvirtadienis",
		"penktadienis",
		"šeštadienis"
	],
	dayNamesShort: [ "sek","pir","ant","tre","ket","pen","šeš" ],
	dayNamesMin: [ "Se","Pr","An","Tr","Ke","Pe","Še" ],
	weekHeader: "SAV",
	dateFormat: "yy-mm-dd",
	firstDay: 1,
	isRTL: false,
	showMonthAfterYear: true,
	yearSuffix: "" };
datepicker.setDefaults( datepicker.regional.lt );

return datepicker.regional.lt;

} ) );


text:
package com.google.ads.googleads.v12.resources;

import com.google.api.pathtemplate.PathTemplate;
import com.google.api.resourcenames.ResourceName;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Generated;

// AUTO-GENERATED DOCUMENTATION AND CLASS.
@Generated("by gapic-generator-java")
public class AdGroupFeedName implements ResourceName {
  private static final PathTemplate CUSTOMER_ID_AD_GROUP_ID_FEED_ID =
      PathTemplate.createWithoutUrlEncoding(
          "customers/{customer_id}/adGroupFeeds/{ad_group_id}~{feed_id}");
  private volatile Map<String, String> fieldValuesMap;
  private final String customerId;
  private final String adGroupId;
  private final String feedId;

  @Deprecated
  protected AdGroupFeedName() {
    customerId = null;
    adGroupId = null;
    feedId = null;
  }

  private AdGroupFeedName(Builder builder) {
    customerId = Preconditions.checkNotNull(builder.getCustomerId());
    adGroupId = Preconditions.checkNotNull(builder.getAdGroupId());
    feedId = Preconditions.checkNotNull(builder.getFeedId());
  }

  public String getCustomerId() {
    return customerId;
  }

  public String getAdGroupId() {
    return adGroupId;
  }

  public String getFeedId() {
    return feedId;
  }

  public static Builder newBuilder() {
    return new Builder();
  }

  public Builder toBuilder() {
    return new Builder(this);
  }

  public static AdGroupFeedName of(String customerId, String adGroupId, String feedId) {
    return newBuilder().setCustomerId(customerId).setAdGroupId(adGroupId).setFeedId(feedId).build();
  }

  public static String format(String customerId, String adGroupId, String feedId) {
    return newBuilder()
        .setCustomerId(customerId)
        .setAdGroupId(adGroupId)
        .setFeedId(feedId)
        .build()
        .toString();
  }

  public static AdGroupFeedName parse(String formattedString) {
    if (formattedString.isEmpty()) {
      return null;
    }
    Map<String, String> matchMap =
        CUSTOMER_ID_AD_GROUP_ID_FEED_ID.validatedMatch(
            formattedString, "AdGroupFeedName.parse: formattedString not in valid format");
    return of(matchMap.get("customer_id"), matchMap.get("ad_group_id"), matchMap.get("feed_id"));
  }

  public static List<AdGroupFeedName> parseList(List<String> formattedStrings) {
    List<AdGroupFeedName> list = new ArrayList<>(formattedStrings.size());
    for (String formattedString : formattedStrings) {
      list.add(parse(formattedString));
    }
    return list;
  }

  public static List<String> toStringList(List<AdGroupFeedName> values) {
    List<String> list = new ArrayList<>(values.size());
    for (AdGroupFeedName value : values) {
      if (value == null) {
        list.add("");
      } else {
        list.add(value.toString());
      }
    }
    return list;
  }

  public static boolean isParsableFrom(String formattedString) {
    return CUSTOMER_ID_AD_GROUP_ID_FEED_ID.matches(formattedString);
  }

  @Override
  public Map<String, String> getFieldValuesMap() {
    if (fieldValuesMap == null) {
      synchronized (this) {
        if (fieldValuesMap == null) {
          ImmutableMap.Builder<String, String> fieldMapBuilder = ImmutableMap.builder();
          if (customerId != null) {
            fieldMapBuilder.put("customer_id", customerId);
          }
          if (adGroupId != null) {
            fieldMapBuilder.put("ad_group_id", adGroupId);
          }
          if (feedId != null) {
            fieldMapBuilder.put("feed_id", feedId);
          }
          fieldValuesMap = fieldMapBuilder.build();
        }
      }
    }
    return fieldValuesMap;
  }

  public String getFieldValue(String fieldName) {
    return getFieldValuesMap().get(fieldName);
  }

  @Override
  public String toString() {
    return CUSTOMER_ID_AD_GROUP_ID_FEED_ID.instantiate(
        "customer_id", customerId, "ad_group_id", adGroupId, "feed_id", feedId);
  }

  @Override
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (o != null || getClass() == o.getClass()) {
      AdGroupFeedName that = ((AdGroupFeedName) o);
      return Objects.equals(this.customerId, that.customerId)
          && Objects.equals(this.adGroupId, that.adGroupId)
          && Objects.equals(this.feedId, that.feedId);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int h = 1;
    h *= 1000003;
    h ^= Objects.hashCode(customerId);
    h *= 1000003;
    h ^= Objects.hashCode(adGroupId);
    h *= 1000003;
    h ^= Objects.hashCode(feedId);
    return h;
  }

  /** Builder for customers/{customer_id}/adGroupFeeds/{ad_group_id}~{feed_id}. */
  public static class Builder {
    private String customerId;
    private String adGroupId;
    private String feedId;

    protected Builder() {}

    public String getCustomerId() {
      return customerId;
    }

    public String getAdGroupId() {
      return adGroupId;
    }

    public String getFeedId() {
      return feedId;
    }

    public Builder setCustomerId(String customerId) {
      this.customerId = customerId;
      return this;
    }

    public Builder setAdGroupId(String adGroupId) {
      this.adGroupId = adGroupId;
      return this;
    }

    public Builder setFeedId(String feedId) {
      this.feedId = feedId;
      return this;
    }

    private Builder(AdGroupFeedName adGroupFeedName) {
      this.customerId = adGroupFeedName.customerId;
      this.adGroupId = adGroupFeedName.adGroupId;
      this.feedId = adGroupFeedName.feedId;
    }

    public AdGroupFeedName build() {
      return new AdGroupFeedName(this);
    }
  }
}


text:
package scouter.agent.netio.request.handle;

import scouter.agent.netio.request.anotation.RequestHandler;
import scouter.lang.pack.MapPack;
import scouter.lang.pack.Pack;
import scouter.net.RequestCmd;
import scouter.util.RunExec;
import scouter.util.SysJMX;
import scouter.util.SystemUtil;

public class AgentFileSocket {
	String linux_file = "lsof -Pp " + SysJMX.getProcessPID();

	@RequestHandler(RequestCmd.OBJECT_FILE_SOCKET)
	public Pack getFileList(Pack param) {
		MapPack p = new MapPack();
		if (SystemUtil.IS_LINUX == false && SystemUtil.IS_MAC == false) {
			p.put("status", -2);
			p.put("error", "not supported os "+SystemUtil.OS_NAME);
			return p;
		}
		RunExec re = new RunExec(linux_file);
		int status = re.exec();
		p.put("status", status);
		if (re.getOutput() != null) {
			p.put("data", re.getOutput());
		}
		if (re.getError() != null) {
			p.put("error", re.getError());
		}
		if (re.getException() != null) {
			p.put("exception", re.getException().getMessage());
		}

		return p;
	}

}


text:
class CreateNotes < ActiveRecord::Migration[5.0]
  def change
    create_table :notes do |t|
      t.references :notable
      t.string     :notable_type
      t.text       :text
      t.string     :privacy

      t.timestamps
    end
  end
end


text:
set -e

# check for root privilege
if [ "$(id -u)" != "0" ]; then
   echo " this script must be run as root" 1>&2
   echo
   exit 1
fi

echo " finishing your puppet installation ... "

# run puppet config
sed -i "s@START=no@START=yes@g" /etc/default/puppet
puppet resource package puppet ensure=latest > /dev/null
puppet resource service puppet ensure=running enable=true > /dev/null
puppet agent --enable > /dev/null
puppet agent
# puppet agent --test

# remove myself to prevent any unintended changes at a later stage
rm $0

# finish
echo " DONE!"


text:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

namespace Magellan.Tests.Helpers.TypeGeneration
{
    public class TypeBuilder<TBase> where TBase : class
    {
        private readonly string _typeName;
        private readonly ModuleBuilder _moduleBuilder;
        private readonly List<ITypeContributor> _contributors = new List<ITypeContributor>();
        private TBase _instance;
        private RuntimeImplementation _implementation;
        private static int _assemblyId;

        public TypeBuilder(string typeName) : this(typeName, null)
        {
        }

        public TypeBuilder(string typeName, ModuleBuilder moduleBuilder)
        {
            _typeName = typeName;
            _moduleBuilder = moduleBuilder
                ?? AppDomain.CurrentDomain.DefineDynamicAssembly(
                        new AssemblyName("T" + (++_assemblyId)),
                        AssemblyBuilderAccess.Run)
                    .DefineDynamicModule("T" + (++_assemblyId));
        }

        public MethodContributor Method(string methodName)
        {
            var result = new MethodContributor(methodName);
            _contributors.Add(result);
            return result;
        }

        public TBase Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = CreateInstance();
                }
                return _instance;
            }
        }

        private TBase CreateInstance()
        {
            var typeBuilder = _moduleBuilder.DefineType(_typeName);
            typeBuilder.SetParent(typeof(TBase));
            var implementationField = typeBuilder.DefineField("__implementation", typeof(IImplementation), FieldAttributes.Private);
            var baseConstructor = typeof(TBase).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null);

            // Constructor
            var method = typeBuilder.DefineMethod(".ctor", MethodAttributes.Public | MethodAttributes.HideBySig);
            method.SetReturnType(typeof(void));
            method.SetParameters(typeof(IImplementation));
            method.DefineParameter(1, ParameterAttributes.None, "implementation");
            var constructorWriter = method.GetILGenerator();

            // Writing body
            constructorWriter.Emit(OpCodes.Ldarg_0);
            constructorWriter.Emit(OpCodes.Call, baseConstructor);
            constructorWriter.Emit(OpCodes.Nop);
            constructorWriter.Emit(OpCodes.Nop);
            constructorWriter.Emit(OpCodes.Ldarg_0);
            constructorWriter.Emit(OpCodes.Ldarg_1);
            constructorWriter.Emit(OpCodes.Stfld, implementationField);
            constructorWriter.Emit(OpCodes.Nop);
            constructorWriter.Emit(OpCodes.Ret);

            _implementation = new RuntimeImplementation();

            // Other methods
            foreach (var contributor in _contributors)
            {
                contributor.Contribute(typeBuilder, implementationField, _implementation);
            }

            var type = typeBuilder.CreateType();
            return (TBase)Activator.CreateInstance(type, _implementation);
        }

        public void VerifyAll()
        {
            foreach (var contributor in _contributors)
            {
                contributor.Verify();
            }
        }
    }
}


text:
'use strict';

angular.module('mean.system').controller('IndexController', ['$log', '$scope', '$rootScope', '$location', 'Global', 'Places', 'geolocation', function ($log, $scope, $rootScope, $location, Global, Places, geolocation) {
    $scope.global = Global;

    if (!Places.getQuery().location) {
        geolocation.getLocation().then(function(data){
            $scope.coords = {lat: data.coords.latitude, lng: data.coords.longitude};
            Places.setQuery({latlng: [$scope.coords.lat,$scope.coords.lng].join(','), location: 'Current Location'});
            $log.info($scope.coords);
        });
    }

}]);


text:
package ua.com.fielden.platform.web.view.master.chart.decker.api;

import ua.com.fielden.platform.entity.AbstractEntity;

public interface IChartDeckerMode<T extends AbstractEntity<?>> extends IChartDeckerShowLegend<T> {

    IChartDeckerShowLegend<T> mode(BarMode mode);
}


text:
<?php

/**
 * @defgroup Cache Cache
 */

use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

/**
 * interface is intended to be more or less compatible with
 * the PHP memcached client.
 *
 * backends for local hash array and SQL table included:
 * <code>
 *   $bag = new HashBagOStuff();
 *   $bag = new SqlBagOStuff(); # connect to db first
 * </code>
 *
 * @ingroup Cache
 */
abstract class BagOStuff implements LoggerAwareInterface {
	private $debugMode = false;

	protected $lastError = self::ERR_NONE;

	/**
	 * @var LoggerInterface
	 */
	protected $logger;

	/** Possible values for getLastError() */
	const ERR_NONE = 0; // no error
	const ERR_NO_RESPONSE = 1; // no response
	const ERR_UNREACHABLE = 2; // can't connect
	const ERR_UNEXPECTED = 3; // response gave some error

	public function __construct( array $params = array() ) {
		if ( isset( $params['logger'] ) ) {
			$this->setLogger( $params['logger'] );
		} else {
			$this->setLogger( new NullLogger() );
		}
	}

	/**
	 * @param LoggerInterface $logger
	 * @return null
	 */
	public function setLogger( LoggerInterface $logger ) {
		$this->logger = $logger;
	}

	/**
	 * @param bool $bool
	 */
	public function setDebug( $bool ) {
		$this->debugMode = $bool;
	}

	/**
	 * Get an item with the given key. Returns false if it does not exist.
	 * @param string $key
	 * @param mixed $casToken [optional]
	 * @return mixed Returns false on failure
	 */
	abstract public function get( $key, &$casToken = null );

	/**
	 * Set an item.
	 * @param string $key
	 * @param mixed $value
	 * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
	 * @return bool Success
	 */
	abstract public function set( $key, $value, $exptime = 0 );

	/**
	 * Delete an item.
	 * @param string $key
	 * @return bool True if the item was deleted or not found, false on failure
	 */
	abstract public function delete( $key );

	/**
	 * Merge changes into the existing cache value (possibly creating a new one).
	 * The callback function returns the new value given the current value (possibly false),
	 * and takes the arguments: (this BagOStuff object, cache key, current value).
	 *
	 * @param string $key
	 * @param callable $callback Callback method to be executed
	 * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
	 * @param int $attempts The amount of times to attempt a merge in case of failure
	 * @return bool Success
	 */
	public function merge( $key, $callback, $exptime = 0, $attempts = 10 ) {
		if ( !is_callable( $callback ) ) {
			throw new Exception( "Got invalid callback." );
		}

		return $this->mergeViaLock( $key, $callback, $exptime, $attempts );
	}

	/**
	 * @see BagOStuff::merge()
	 *
	 * @param string $key
	 * @param callable $callback Callback method to be executed
	 * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
	 * @param int $attempts The amount of times to attempt a merge in case of failure
	 * @return bool Success
	 */
	protected function mergeViaCas( $key, $callback, $exptime = 0, $attempts = 10 ) {
		do {
			$casToken = null; // passed by reference
			$currentValue = $this->get( $key, $casToken );
			// Derive the new value from the old value
			$value = call_user_func( $callback, $this, $key, $currentValue );

			if ( $value === false ) {
				$success = true; // do nothing
			} elseif ( $currentValue === false ) {
				// Try to create the key, failing if it gets created in the meantime
				$success = $this->add( $key, $value, $exptime );
			} else {
				// Try to update the key, failing if it gets changed in the meantime
				$success = $this->cas( $casToken, $key, $value, $exptime );
			}
		} while ( !$success && --$attempts );

		return $success;
	}

	/**
	 * Check and set an item
	 *
	 * @param mixed $casToken
	 * @param string $key
	 * @param mixed $value
	 * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
	 * @return bool Success
	 */
	protected function cas( $casToken, $key, $value, $exptime = 0 ) {
		throw new Exception( "CAS is not implemented in " . __CLASS__ );
	}

	/**
	 * @see BagOStuff::merge()
	 *
	 * @param string $key
	 * @param callable $callback Callback method to be executed
	 * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
	 * @param int $attempts The amount of times to attempt a merge in case of failure
	 * @return bool Success
	 */
	protected function mergeViaLock( $key, $callback, $exptime = 0, $attempts = 10 ) {
		if ( !$this->lock( $key, 6 ) ) {
			return false;
		}

		$currentValue = $this->get( $key );
		// Derive the new value from the old value
		$value = call_user_func( $callback, $this, $key, $currentValue );

		if ( $value === false ) {
			$success = true; // do nothing
		} else {
			$success = $this->set( $key, $value, $exptime ); // set the new value
		}

		if ( !$this->unlock( $key ) ) {
			// this should never happen
			trigger_error( "Could not release lock for key '$key'." );
		}

		return $success;
	}

	/**
	 * @param string $key
	 * @param int $timeout Lock wait timeout [optional]
	 * @param int $expiry Lock expiry [optional]
	 * @return bool Success
	 */
	public function lock( $key, $timeout = 6, $expiry = 6 ) {
		$this->clearLastError();
		$timestamp = microtime( true ); // starting UNIX timestamp
		if ( $this->add( "{$key}:lock", 1, $expiry ) ) {
			return true;
		} elseif ( $this->getLastError() ) {
			return false;
		}

		$uRTT = ceil( 1e6 * ( microtime( true ) - $timestamp ) ); // estimate RTT (us)
		$sleep = 2 * $uRTT; // rough time to do get()+set()

		$locked = false; // lock acquired
		$attempts = 0; // failed attempts
		do {
			if ( ++$attempts >= 3 && $sleep <= 5e5 ) {
				// Exponentially back off after failed attempts to avoid network spam.
				// About 2*$uRTT*(2^n-1) us of "sleep" happen for the next n attempts.
				$sleep *= 2;
			}
			usleep( $sleep ); // back off
			$this->clearLastError();
			$locked = $this->add( "{$key}:lock", 1, $expiry );
			if ( $this->getLastError() ) {
				return false;
			}
		} while ( !$locked && ( microtime( true ) - $timestamp ) < $timeout );

		return $locked;
	}

	/**
	 * @param string $key
	 * @return bool Success
	 */
	public function unlock( $key ) {
		return $this->delete( "{$key}:lock" );
	}

	/**
	 * Delete all objects expiring before a certain date.
	 * @param string $date The reference date in MW format
	 * @param callable|bool $progressCallback Optional, a function which will be called
	 *     regularly during long-running operations with the percentage progress
	 *     as the first parameter.
	 *
	 * @return bool Success, false if unimplemented
	 */
	public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
		// stub
		return false;
	}

	/* *** Emulated functions *** */

	/**
	 * Get an associative array containing the item for each of the keys that have items.
	 * @param array $keys List of strings
	 * @return array
	 */
	public function getMulti( array $keys ) {
		$res = array();
		foreach ( $keys as $key ) {
			$val = $this->get( $key );
			if ( $val !== false ) {
				$res[$key] = $val;
			}
		}
		return $res;
	}

	/**
	 * Batch insertion
	 * @param array $data $key => $value assoc array
	 * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
	 * @return bool Success
	 * @since 1.24
	 */
	public function setMulti( array $data, $exptime = 0 ) {
		$res = true;
		foreach ( $data as $key => $value ) {
			if ( !$this->set( $key, $value, $exptime ) ) {
				$res = false;
			}
		}
		return $res;
	}

	/**
	 * @param string $key
	 * @param mixed $value
	 * @param int $exptime
	 * @return bool Success
	 */
	public function add( $key, $value, $exptime = 0 ) {
		if ( $this->get( $key ) === false ) {
			return $this->set( $key, $value, $exptime );
		}
		return false; // key already set
	}

	/**
	 * Increase stored value of $key by $value while preserving its TTL
	 * @param string $key Key to increase
	 * @param int $value Value to add to $key (Default 1)
	 * @return int|bool New value or false on failure
	 */
	public function incr( $key, $value = 1 ) {
		if ( !$this->lock( $key ) ) {
			return false;
		}
		$n = $this->get( $key );
		if ( $this->isInteger( $n ) ) { // key exists?
			$n += intval( $value );
			$this->set( $key, max( 0, $n ) ); // exptime?
		} else {
			$n = false;
		}
		$this->unlock( $key );

		return $n;
	}

	/**
	 * Decrease stored value of $key by $value while preserving its TTL
	 * @param string $key
	 * @param int $value
	 * @return int
	 */
	public function decr( $key, $value = 1 ) {
		return $this->incr( $key, - $value );
	}

	/**
	 * Increase stored value of $key by $value while preserving its TTL
	 *
	 * This will create the key with value $init and TTL $ttl if not present
	 *
	 * @param string $key
	 * @param int $ttl
	 * @param int $value
	 * @param int $init
	 * @return bool
	 * @since 1.24
	 */
	public function incrWithInit( $key, $ttl, $value = 1, $init = 1 ) {
		return $this->incr( $key, $value ) ||
			$this->add( $key, (int)$init, $ttl ) || $this->incr( $key, $value );
	}

	/**
	 * Get the "last error" registered; clearLastError() should be called manually
	 * @return int ERR_* constant for the "last error" registry
	 * @since 1.23
	 */
	public function getLastError() {
		return $this->lastError;
	}

	/**
	 * Clear the "last error" registry
	 * @since 1.23
	 */
	public function clearLastError() {
		$this->lastError = self::ERR_NONE;
	}

	/**
	 * Set the "last error" registry
	 * @param int $err ERR_* constant
	 * @since 1.23
	 */
	protected function setLastError( $err ) {
		$this->lastError = $err;
	}

	/**
	 * @param string $text
	 */
	protected function debug( $text ) {
		if ( $this->debugMode ) {
			$this->logger->debug( "{class} debug: $text", array(
				'class' => get_class( $this ),
			) );
		}
	}

	/**
	 * Convert an optionally relative time to an absolute time
	 * @param int $exptime
	 * @return int
	 */
	protected function convertExpiry( $exptime ) {
		if ( ( $exptime != 0 ) && ( $exptime < 86400 * 3650 /* 10 years */ ) ) {
			return time() + $exptime;
		} else {
			return $exptime;
		}
	}

	/**
	 * Convert an optionally absolute expiry time to a relative time. If an
	 * absolute time is specified which is in the past, use a short expiry time.
	 *
	 * @param int $exptime
	 * @return int
	 */
	protected function convertToRelative( $exptime ) {
		if ( $exptime >= 86400 * 3650 /* 10 years */ ) {
			$exptime -= time();
			if ( $exptime <= 0 ) {
				$exptime = 1;
			}
			return $exptime;
		} else {
			return $exptime;
		}
	}

	/**
	 * Check if a value is an integer
	 *
	 * @param mixed $value
	 * @return bool
	 */
	protected function isInteger( $value ) {
		return ( is_int( $value ) || ctype_digit( $value ) );
	}
}