docs: public static String encode(String decoded_string, String crypto_algorithm, Map<String, String> properties)
                      throws InvalidPasswordEncodingException, UnsupportedCryptoAlgorithmException {
          /*
           * check input:
           * 
           * -- decoded_string: any string, any length, cannot be null,
           * cannot start with crypto algorithm tag
           * 
           * -- crypto_algorithm: any string, any length, cannot be null,
           * must be valid (supported) crypto algorithm
           */
  
          if (!isValidCryptoAlgorithm(crypto_algorithm)) {
              // don't accept unsupported crypto algorithm
              throw new UnsupportedCryptoAlgorithmException();
          }
  
          if (decoded_string == null) {
              // don't accept null password
              throw new InvalidPasswordEncodingException();
          }
  
          String current_crypto_algorithm = getCryptoAlgorithm(decoded_string);
  
          if ((current_crypto_algorithm != null && current_crypto_algorithm.startsWith(crypto_algorithm)) || isHashed(decoded_string)) {
              // don't accept encoded password
              throw new InvalidPasswordEncodingException();
          } else if (current_crypto_algorithm != null) {
              decoded_string = passwordDecode(decoded_string);
          }
          if (properties == null || !properties.containsKey(PROPERTY_NO_TRIM) || !"true".equalsIgnoreCase(properties.get(PROPERTY_NO_TRIM))) {
              decoded_string = decoded_string.trim();
          }
          String encoded_string = encode_password(decoded_string, crypto_algorithm.trim(), properties);
  
          if (encoded_string == null) {
              throw new InvalidPasswordEncodingException();
          }
  
          return encoded_string;
      }