docs: @SuppressWarnings({"checkstyle:cyclomaticcomplexity", "npathcomplexity"})
  	public static void splitOptionsAndParameters(String... optionDefinitions) {
  		if (analyzed) {
  			return;
  		}
  
  		final List<String> params = new ArrayList<>();
  		final SortedMap<String, List<Object>> options = new TreeMap<>();
  		String opt;
  
  		// Analyze definitions
  		final Map<String, OptionType> defs = new TreeMap<>();
  		for (final String def : optionDefinitions) {
  			if (def.endsWith("!")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 1);
  				defs.put(opt, OptionType.FLAG);
  				registerOptionValue(options, opt, Boolean.FALSE, OptionType.FLAG);
  			} else if (def.endsWith("+")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 1);
  				defs.put(opt, OptionType.AUTO_INCREMENTED);
  				registerOptionValue(options, opt, Long.valueOf(0), OptionType.AUTO_INCREMENTED);
  			} else if (def.endsWith("=b")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 2);
  				defs.put(opt, OptionType.MANDATORY_BOOLEAN);
  			} else if (def.endsWith(":b")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 2);
  				defs.put(opt, OptionType.OPTIONAL_BOOLEAN);
  			} else if (def.endsWith("=f")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 2);
  				defs.put(opt, OptionType.MANDATORY_FLOAT);
  			} else if (def.endsWith(":f")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 2);
  				defs.put(opt, OptionType.OPTIONAL_FLOAT);
  			} else if (def.endsWith("=i")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 2);
  				defs.put(opt, OptionType.MANDATORY_INTEGER);
  			} else if (def.endsWith(":i")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 2);
  				defs.put(opt, OptionType.OPTIONAL_INTEGER);
  			} else if (def.endsWith("=s")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 2);
  				defs.put(opt, OptionType.MANDATORY_STRING);
  			} else if (def.endsWith(":s")) { //$NON-NLS-1$
  				opt = def.substring(0, def.length() - 2);
  				defs.put(opt, OptionType.OPTIONAL_STRING);
  			} else {
  				defs.put(def, OptionType.SIMPLE);
  			}
  		}
  
  		int idx;
  		String base;
  		String nbase;
  		String val;
  		OptionType type;
  		OptionType waitingValue = null;
  		String valueOptionName = null;
  		boolean allParameters = false;
  		boolean success;
  
  		for (final String param : commandLineParameters) {
  			if (allParameters) {
  				params.add(param);
  				continue;
  			}
  
  			if (waitingValue != null && waitingValue.isMandatory()) {
  				// Expect a value as the next parameter
  				success = registerOptionValue(options, valueOptionName, param, waitingValue);
  				waitingValue = null;
  				valueOptionName = null;
  				if (success) {
  					continue;
  				}
  			}
  
  			if ("--".equals(param)) { //$NON-NLS-1$
  				if (waitingValue != null) {
  					registerOptionValue(options, valueOptionName, null, waitingValue);
  					waitingValue = null;
  					valueOptionName = null;
  				}
  				allParameters = true;
  				continue;
  			} else if ((File.separatorChar != '/') && (param.startsWith("/"))) { //$NON-NLS-1$
  				opt = param.substring(1);
  			} else if (param.startsWith("--")) { //$NON-NLS-1$
  				opt = param.substring(2);
  			} else if (param.startsWith("-")) { //$NON-NLS-1$
  				opt = param.substring(1);
  			} else if (waitingValue != null) {
  				success = registerOptionValue(options, valueOptionName, param, waitingValue);
  				waitingValue = null;
  				valueOptionName = null;
  				if (!success) {
  					params.add(param);
  				}
  				continue;
  			} else {
  				params.add(param);
  				continue;
  			}
  
  			if (waitingValue != null) {
  				success = registerOptionValue(options, valueOptionName, param, waitingValue);
  				waitingValue = null;
  				valueOptionName = null;
  				if (success) {
  					continue;
  				}
  			}
  
  			idx = opt.indexOf('=');
  			if (idx > 0) {
  				base = opt.substring(0, idx);
  				val = opt.substring(idx + 1);
  			} else {
  				base = opt;
  				val = null;
  			}
  
  			nbase = null;
  			type = defs.get(base);
  			if (type == null && base.toLowerCase().startsWith("no")) { //$NON-NLS-1$
  				nbase = base.substring(2);
  				type = defs.get(nbase);
  			}
  			if (type != null) {
  				switch (type) {
  				case FLAG:
  					if (nbase == null) {
  						registerOptionValue(options, base, Boolean.TRUE, type);
  					} else {
  						registerOptionValue(options, nbase, Boolean.FALSE, type);
  					}
  					break;
  				case MANDATORY_FLOAT:
  				case MANDATORY_BOOLEAN:
  				case MANDATORY_INTEGER:
  				case MANDATORY_STRING:
  				case OPTIONAL_FLOAT:
  				case OPTIONAL_BOOLEAN:
  				case OPTIONAL_INTEGER:
  				case OPTIONAL_STRING:
  					if (val != null) {
  						registerOptionValue(options, base, val, type);
  					} else {
  						waitingValue = type;
  						valueOptionName = base;
  					}
  					break;
  					//$CASES-OMITTED$
  				default:
  					registerOptionValue(options, base, val, type);
  				}
  			} else {
  				// Not a recognized option, assuming simple
  				registerOptionValue(options, base, val, OptionType.SIMPLE);
  			}
  		}
  
  		if (waitingValue != null && waitingValue.isMandatory()) {
  			throw new IllegalStateException(Locale.getString("E2", valueOptionName)); //$NON-NLS-1$
  		}
  
  		commandLineParameters = new String[params.size()];
  		params.toArray(commandLineParameters);
  		params.clear();
  
  		commandLineOptions = options;
  
  		analyzed = true;
  	}