class SW360ConnectionFactory {

    public SW360Connection newConnection(SW360ClientConfig config) {
        SW360AuthenticationClient authClient = new SW360AuthenticationClient(config);
        AccessTokenProvider tokenProvider = new AccessTokenProvider(authClient);

        SW360ComponentClient componentClient = new SW360ComponentClient(config, tokenProvider);
        SW360ComponentClientAdapterAsync componentAdapterAsync =
                new SW360ComponentClientAdapterAsyncImpl(componentClient);
        SW360ComponentClientAdapter componentAdapterSync =
                SyncClientAdapterHandler.newHandler(SW360ComponentClientAdapter.class,
                        SW360ComponentClientAdapterAsync.class, componentAdapterAsync);

        SW360ReleaseClient releaseClient = new SW360ReleaseClient(config, tokenProvider);
        SW360ReleaseClientAdapterAsyncImpl releaseAdapterAsync =
                new SW360ReleaseClientAdapterAsyncImpl(releaseClient, componentAdapterAsync);
        SW360ReleaseClientAdapter releaseAdapterSync =
                SyncClientAdapterHandler.newHandler(SW360ReleaseClientAdapter.class,
                        SW360ReleaseClientAdapterAsync.class, releaseAdapterAsync);

        SW360LicenseClient licenseClient = new SW360LicenseClient(config, tokenProvider);
        SW360LicenseClientAdapterAsync licenseAdapterAsync = new SW360LicenseClientAdapterAsyncImpl(licenseClient);
        SW360LicenseClientAdapter licenseAdapterSync =
                SyncClientAdapterHandler.newHandler(SW360LicenseClientAdapter.class,
                        SW360LicenseClientAdapterAsync.class, licenseAdapterAsync);

        SW360ProjectClient projectClient = new SW360ProjectClient(config, tokenProvider);
        SW360ProjectClientAdapterAsync projectAdapterAsync = new SW360ProjectClientAdapterAsyncImpl(projectClient);
        SW360ProjectClientAdapter projectAdapterSync =
                SyncClientAdapterHandler.newHandler(SW360ProjectClientAdapter.class,
                        SW360ProjectClientAdapterAsync.class, projectAdapterAsync);

        return new SW360Connection() {
            @Override
            public SW360ComponentClientAdapter getComponentAdapter() {
                return componentAdapterSync;
            }

            @Override
            public SW360ComponentClientAdapterAsync getComponentAdapterAsync() {
                return componentAdapterAsync;
            }

            @Override
            public SW360ReleaseClientAdapter getReleaseAdapter() {
                return releaseAdapterSync;
            }

            @Override
            public SW360ReleaseClientAdapterAsync getReleaseAdapterAsync() {
                return releaseAdapterAsync;
            }

            @Override
            public SW360LicenseClientAdapter getLicenseAdapter() {
                return licenseAdapterSync;
            }

            @Override
            public SW360LicenseClientAdapterAsync getLicenseAdapterAsync() {
                return licenseAdapterAsync;
            }

            @Override
            public SW360ProjectClientAdapter getProjectAdapter() {
                return projectAdapterSync;
            }

            @Override
            public SW360ProjectClientAdapterAsync getProjectAdapterAsync() {
                return projectAdapterAsync;
            }
        };
    }

}