docs: public void addProperty(String propertyName, Object propertyValue)
    throws SFException
    {
      SFSessionProperty connectionProperty =
          SFSessionProperty.lookupByKey(propertyName);
  
      if (connectionProperty != null)
      {
        // check if the value type is as expected
        propertyValue = SFSessionProperty
            .checkPropertyValue(connectionProperty, propertyValue);
  
        if (connectionPropertiesMap.containsKey(connectionProperty))
        {
          throw new SFException(ErrorCode.DUPLICATE_CONNECTION_PROPERTY_SPECIFIED,
                                propertyName);
        }
        else
        {
          connectionPropertiesMap.put(connectionProperty, propertyValue);
        }
  
        switch (connectionProperty)
        {
          case LOGIN_TIMEOUT:
            if (propertyValue != null)
            {
              loginTimeout = (Integer) propertyValue;
            }
            break;
  
          case NETWORK_TIMEOUT:
            if (propertyValue != null)
            {
              networkTimeoutInMilli = (Integer) propertyValue;
            }
            break;
  
          case INJECT_CLIENT_PAUSE:
            if (propertyValue != null)
            {
              injectClientPause = (Integer) propertyValue;
            }
            break;
  
          case INJECT_SOCKET_TIMEOUT:
            if (propertyValue != null)
            {
              injectSocketTimeout = (Integer) propertyValue;
            }
            break;
  
          case PASSCODE_IN_PASSWORD:
            passcodeInPassword = (propertyValue != null && (Boolean) propertyValue);
            break;
  
          case TRACING:
            if (propertyValue != null)
            {
              tracingLevel = Level.parse(((String) propertyValue).toUpperCase());
              if (tracingLevel != null && logger instanceof JDK14Logger)
              {
                JDK14Logger.honorTracingParameter(tracingLevel);
              }
            }
            break;
  
          case DISABLE_SOCKS_PROXY:
            // note: if any session has this parameter, it will be used for all
            // sessions on the current JVM.
            if (propertyValue != null)
            {
              HttpUtil.setSocksProxyDisabled((Boolean) propertyValue);
            }
  
          default:
            break;
        }
      }
      else
      {
        // this property does not match any predefined property, treat it as
        // session parameter
        if (sessionParametersMap.containsKey(propertyName))
        {
          throw new SFException(ErrorCode.DUPLICATE_CONNECTION_PROPERTY_SPECIFIED,
                                propertyName);
        }
        else
        {
          sessionParametersMap.put(propertyName, propertyValue);
        }
  
        // check if the number of session properties exceed limit
        if (sessionParametersMap.size() > MAX_SESSION_PARAMETERS)
        {
          throw new SFException(ErrorCode.TOO_MANY_SESSION_PARAMETERS,
                                MAX_SESSION_PARAMETERS);
        }
      }
    }