@Override
	public final void connect() throws CommunicationError, ConnectionException {
		synchronized(_lock) {
			if(_isConnected) {
				throw new RuntimeException("Verbindung zum Datenverteiler besteht bereits.");
			}
			if(_dataModelConnection != null) {
				_dataModelConnection.connect();
				_dataModel = _dataModelConnection.getDataModel();
				((DafDataModel)this._dataModel).setPublicConnection(this);
			}
			if(_reinitializeOnConnect) {
				if(_dataModel instanceof DafDataModel && _dataModelConnection == null) {
					createDataModel();
				}
				_closeHandler.reset();
				_cacheManager = null;
				_configurationManager = null;
				_subscriptionManager = null;
				if(_implicitUnsubscriber != null) {
					try {
						_implicitUnsubscriber.interrupt();
						_implicitUnsubscriber.join();
					}
					catch(InterruptedException e) {
						throw new RuntimeException(e);
					}
				}
				_implicitSubscriptionDataReceived = new Object();
				_implicitSubscriptions = new Hashtable<BaseSubscriptionInfo, ImplicitSubscriptionNote>();
				_implicitUnsubscriber = null;
				_streamedRequestManager = null;
				_defaultData = new HashMap<AttributeGroup, Data>();
				_readyMessageSender = null;
			}
			
			_reinitializeOnConnect = true;
			if(_highLevelCommunication != null) {
				_highLevelCommunication.terminate(false, "Verbindung soll erneut aufgebaut werden");
			}
			_highLevelCommunication = new ClientHighLevelCommunication(_clientDavParameters, _closeHandler);
			_highLevelCommunication.setConnectionListener(
					new DavConnectionListener() {
						@Override
						public void connectionClosed(ClientDavInterface nullConnection) {
							notifyConnectionClosed();
						}
					}
			);
			_isConnected = true;
			_isLoggedIn = false;
			if(_implicitUnsubscriber == null) {
				_implicitUnsubscriber = new ImplicitUnsubscriber();
				_implicitUnsubscriber.start();
			}
		}
	}