docs: public static TaskManagerConfiguration fromConfiguration(Configuration configuration) {
  		int numberSlots = configuration.getInteger(TaskManagerOptions.NUM_TASK_SLOTS, 1);
  
  		if (numberSlots == -1) {
  			numberSlots = 1;
  		}
  
  		final String[] tmpDirPaths = ConfigurationUtils.parseTempDirectories(configuration);
  
  		final Time timeout;
  
  		try {
  			timeout = Time.milliseconds(AkkaUtils.getTimeout(configuration).toMillis());
  		} catch (Exception e) {
  			throw new IllegalArgumentException(
  				"Invalid format for '" + AkkaOptions.ASK_TIMEOUT.key() +
  					"'.Use formats like '50 s' or '1 min' to specify the timeout.");
  		}
  
  		LOG.info("Messages have a max timeout of " + timeout);
  
  		final Time finiteRegistrationDuration;
  
  		try {
  			Duration maxRegistrationDuration = Duration.create(configuration.getString(TaskManagerOptions.REGISTRATION_TIMEOUT));
  			if (maxRegistrationDuration.isFinite()) {
  				finiteRegistrationDuration = Time.milliseconds(maxRegistrationDuration.toMillis());
  			} else {
  				finiteRegistrationDuration = null;
  			}
  		} catch (NumberFormatException e) {
  			throw new IllegalArgumentException("Invalid format for parameter " +
  				TaskManagerOptions.REGISTRATION_TIMEOUT.key(), e);
  		}
  
  		final Time initialRegistrationPause;
  		try {
  			Duration pause = Duration.create(configuration.getString(TaskManagerOptions.INITIAL_REGISTRATION_BACKOFF));
  			if (pause.isFinite()) {
  				initialRegistrationPause = Time.milliseconds(pause.toMillis());
  			} else {
  				throw new IllegalArgumentException("The initial registration pause must be finite: " + pause);
  			}
  		} catch (NumberFormatException e) {
  			throw new IllegalArgumentException("Invalid format for parameter " +
  				TaskManagerOptions.INITIAL_REGISTRATION_BACKOFF.key(), e);
  		}
  
  		final Time maxRegistrationPause;
  		try {
  			Duration pause = Duration.create(configuration.getString(
  				TaskManagerOptions.REGISTRATION_MAX_BACKOFF));
  			if (pause.isFinite()) {
  				maxRegistrationPause = Time.milliseconds(pause.toMillis());
  			} else {
  				throw new IllegalArgumentException("The maximum registration pause must be finite: " + pause);
  			}
  		} catch (NumberFormatException e) {
  			throw new IllegalArgumentException("Invalid format for parameter " +
  				TaskManagerOptions.INITIAL_REGISTRATION_BACKOFF.key(), e);
  		}
  
  		final Time refusedRegistrationPause;
  		try {
  			Duration pause = Duration.create(configuration.getString(TaskManagerOptions.REFUSED_REGISTRATION_BACKOFF));
  			if (pause.isFinite()) {
  				refusedRegistrationPause = Time.milliseconds(pause.toMillis());
  			} else {
  				throw new IllegalArgumentException("The refused registration pause must be finite: " + pause);
  			}
  		} catch (NumberFormatException e) {
  			throw new IllegalArgumentException("Invalid format for parameter " +
  				TaskManagerOptions.INITIAL_REGISTRATION_BACKOFF.key(), e);
  		}
  
  		final boolean exitOnOom = configuration.getBoolean(TaskManagerOptions.KILL_ON_OUT_OF_MEMORY);
  
  		final String classLoaderResolveOrder =
  			configuration.getString(CoreOptions.CLASSLOADER_RESOLVE_ORDER);
  
  		final String[] alwaysParentFirstLoaderPatterns = CoreOptions.getParentFirstLoaderPatterns(configuration);
  
  		final String taskManagerLogPath = configuration.getString(ConfigConstants.TASK_MANAGER_LOG_PATH_KEY, System.getProperty("log.file"));
  		final String taskManagerStdoutPath;
  
  		if (taskManagerLogPath != null) {
  			final int extension = taskManagerLogPath.lastIndexOf('.');
  
  			if (extension > 0) {
  				taskManagerStdoutPath = taskManagerLogPath.substring(0, extension) + ".out";
  			} else {
  				taskManagerStdoutPath = null;
  			}
  		} else {
  			taskManagerStdoutPath = null;
  		}
  
  		final RetryingRegistrationConfiguration retryingRegistrationConfiguration = RetryingRegistrationConfiguration.fromConfiguration(configuration);
  
  		return new TaskManagerConfiguration(
  			numberSlots,
  			tmpDirPaths,
  			timeout,
  			finiteRegistrationDuration,
  			initialRegistrationPause,
  			maxRegistrationPause,
  			refusedRegistrationPause,
  			configuration,
  			exitOnOom,
  			FlinkUserCodeClassLoaders.ResolveOrder.fromString(classLoaderResolveOrder),
  			alwaysParentFirstLoaderPatterns,
  			taskManagerLogPath,
  			taskManagerStdoutPath,
  			retryingRegistrationConfiguration);
  	}