class AbstractAdapterConfigBuilder {

	public final C build() {
		validate();
		ensureTimeSetup();
		ensureTraceID();

		C config = buildInitialConfig();
		if (!( config instanceof AbstractAdapterConfig)) {
			throw new IllegalStateException(getClass().getName()+" does not return a child of AbstractAdapterConfig!");
		}
		Set<URI> shrinkedRootURIs = uriShrinker.shrinkToRootURIs(targetURIs);

		AbstractAdapterConfig abstractAdapterConfig = (AbstractAdapterConfig) config;

		abstractAdapterConfig.productBaseURL = productBaseURL;

		abstractAdapterConfig.timeToWaitForNextCheckOperationInMilliseconds = timeToWaitForNextCheckOperationInMinutes * 60 * 1000;
		abstractAdapterConfig.timeOutInMilliseconds = scanResultTimeOutInMinutes * 60 * 1000;

		abstractAdapterConfig.proxyHostname = proxyHostname;
		abstractAdapterConfig.proxyPort = proxyPort;
		abstractAdapterConfig.user = user;
		abstractAdapterConfig.trustAllCertificatesEnabled=trustAllCertificatesEnabled;
		abstractAdapterConfig.passwordOrAPIToken = passwordOrApiToken;
		abstractAdapterConfig.policyId = policyID;
		abstractAdapterConfig.targetURIs = targetURIs;
		abstractAdapterConfig.rootTargetUris.addAll(shrinkedRootURIs);
		abstractAdapterConfig.targetIPs = targetIPs;

		abstractAdapterConfig.traceID = traceID;
		abstractAdapterConfig.projectId=projectId;
		abstractAdapterConfig.getOptions().putAll(options);

		packageInternalCustomBuild(config);
		customBuild(config);

		return config;
	}

	protected  AbstractAdapterConfigBuilder();

}