private ModuleType determineType(List<ModuleDescriptor> modules) {
		Assert.isTrue(modules != null && modules.size() > 0, "at least one module required");
		if (modules.size() == 1) {
			return modules.get(0).getType();
		}
		Collections.sort(modules);
		ModuleType firstType = modules.get(0).getType();
		ModuleType lastType = modules.get(modules.size() - 1).getType();
		boolean hasInput = firstType != ModuleType.source;
		boolean hasOutput = lastType != ModuleType.sink;
		if (hasInput && hasOutput) {
			return ModuleType.processor;
		}
		if (hasInput) {
			return ModuleType.sink;
		}
		if (hasOutput) {
			return ModuleType.source;
		}
		throw new IllegalArgumentException("invalid module composition; must expose input and/or output channel");
	}
Throws an exception if either one of the following is true:<ul>
    <li>a module with the given name and type already exists and force is {@code false}</li>
    <li>force if {@true} but the module is in use (by a stream or composed module)</li>
</ul>

<p>Also, will actually delete the already existing definition in case of an update,
even though it would be overwritten by a registry, to cover the cases where a composed
module is being replaced by a simple uploaded module, and <i>vice versa</i>.</p>

@param name name of the module we're trying to update/create
@param type type of the module we're trying to update/create
@param force whether to attempt to force update if the module already exists
spring-xd-dirt/src/main/java/org/springframework/xd/dirt/module/support/ModuleDefinitionService.java