/** Thread Runnable that handles received triggers */
 @SuppressWarnings("nls")
 @Override
 public void run() {
   try {
     while (run) {
       // Wait for a trigger
       synchronized (mutex) {
         while (triggers <= 0) {
           mutex.wait();
         }
       }
       // Wait a little longer, so in case of a burst, we update
       // after already receiving more than just the start of the
       // burst
       Thread.sleep(initialMillis);
       synchronized (mutex) {
         triggers = 0;
       }
       if (run) {
         fire();
       }
       // Suppress further updates a little to prevent flicker
       Thread.sleep(suppressionMillis);
     }
   } catch (InterruptedException ex) {
     SaveRestoreService.LOGGER.log(Level.SEVERE, "GUI Update failed", ex);
   }
 }
 /**
  * Returns the git username stored in the secured preferences for the given user. The user is
  * usually the user that is logged in to CS-Studio. If no user is provided, system user is used.
  *
  * @param forUser the user for whom the username is to be retrieved
  * @return the username if it exists, or null otherwise
  */
 public static String getUsername(Optional<String> forUser) {
   String user = forUser.orElse(System.getProperty(SYSTEM_PROPERTY_USER_NAME));
   try {
     return SecurePreferences.getSecurePreferences()
         .node(Activator.ID)
         .node(user)
         .get(PREF_USERNAME, null);
   } catch (StorageException | IOException e) {
     SaveRestoreService.LOGGER.log(
         Level.WARNING, "Could not read the username from secured storage.", e);
     return null;
   }
 }
 /**
  * Stores the username and matching password for a particular user.
  *
  * @param forUser the user for whom the credentials are stored
  * @param username the username to store
  * @param password the password to store
  */
 public static void storeCredentials(Optional<String> forUser, String username, char[] password) {
   String user = forUser.orElse(System.getProperty(SYSTEM_PROPERTY_USER_NAME));
   try {
     ISecurePreferences prefs =
         SecurePreferences.getSecurePreferences().node(Activator.ID).node(user);
     if (username == null) {
       return;
     } else {
       prefs.put(PREF_USERNAME, username, false);
     }
     if (password == null) {
       prefs.node(username).remove(PREF_PASSWORD);
     } else {
       ByteBuffer buffer = StandardCharsets.UTF_8.newEncoder().encode(CharBuffer.wrap(password));
       byte[] passwordData = Arrays.copyOfRange(buffer.array(), buffer.position(), buffer.limit());
       prefs.node(username).putByteArray(PREF_PASSWORD, passwordData, false);
     }
     SaveRestoreService.LOGGER.log(
         Level.FINE, "Stored new username and password for {0}.", new Object[] {user});
   } catch (StorageException | IOException e) {
     SaveRestoreService.LOGGER.log(Level.WARNING, "Could not store the username and password.", e);
   }
 }
 /**
  * Returns the password that is bound to the username and is stored for the specified <code>
  * forUser</code> If the <code>forUser</code> is not specified the system user is used.
  *
  * @param forUser the user for whom the password is being retrieved
  * @param username the matching username to go with the password
  * @return the password as a character array or empty object if password could not be loaded
  */
 public static Optional<char[]> getPassword(Optional<String> forUser, String username) {
   if (username == null) {
     return Optional.empty();
   }
   final String user = forUser.orElse(System.getProperty(SYSTEM_PROPERTY_USER_NAME));
   try {
     byte[] val =
         SecurePreferences.getSecurePreferences()
             .node(Activator.ID)
             .node(user)
             .node(username)
             .getByteArray(PREF_PASSWORD, null);
     if (val != null) {
       CharBuffer buffer = StandardCharsets.UTF_8.newDecoder().decode(ByteBuffer.wrap(val));
       return Optional.of(Arrays.copyOfRange(buffer.array(), buffer.position(), buffer.limit()));
     }
   } catch (StorageException | IOException e) {
     SaveRestoreService.LOGGER.log(
         Level.WARNING,
         e,
         () -> String.format("Could not read the password for '%s' from secured storage.", user));
   }
   return Optional.empty();
 }