class Options {

	public List<String> processFields(@Nonnull String optionSpecsString, @Nullable Object... opts)
			throws OptionsException {
		throwOptionsExceptionIfConditionFails(nonNull(optionSpecsString), "options specs are required");

		List<String> optsList = new ArrayList<>();
		if (nonNull(opts)) {
			String[] optionSpecExpressions = optionSpecsString.split(SPACE);
			throwOptionsExceptionIfConditionFails(optionSpecExpressions.length == opts.length,
					"specs vs opts size mismatch in options processor");

			String currentOptionSpecExpression = EMPTY;
			try {
				for (int i = 0; i < opts.length; i++) {
					currentOptionSpecExpression = optionSpecExpressions[i];
					throwOptionsExceptionIfConditionFails(isNotBlank(currentOptionSpecExpression),
							"null options spec in options processor: %s", optionSpecsString);
					String[] optSpecParts = currentOptionSpecExpression.split(":");

					throwOptionsExceptionIfConditionFails(optSpecParts.length == 2 || optSpecParts.length == 3,
							"null options spec in options processor: %s", optionSpecsString);

					String ruleName = EMPTY;
					if (optSpecParts.length >= 3) {
						ruleName = optSpecParts[2];
					}
					String serverOptionStr = optSpecParts[1];

					String optSpecType = optSpecParts[0];
					OptionsSpecType p4CommandOptions = OptionsSpecType.of(optSpecType);
					optsList.addAll(p4CommandOptions.getP4CommandOptionFields(ruleName, serverOptionStr, opts[i]));
				}
			} catch (Exception exc) {
				throwOptionsException(exc,
						"bad conversion encountered in options processor with option string '%s': %s",
						currentOptionSpecExpression, exc.getLocalizedMessage());
			}
		}

		return optsList;
	}

	public  Options();
	public  Options(String... options);

}