QString SkypeConnection::operator %(const QString &message) {
	kDebug(SKYPE_DEBUG_GLOBAL) << "Send message:" << message;

	if (d->fase == cfNotConnected)
		return QString();//not connected, posibly because of earlier error, do not show it again

	QDBusInterface interface("com.Skype.API", "/com/Skype", "com.Skype.API", BUS);
	QDBusReply <QString> reply = interface.call("Invoke", message);

	if ( interface.lastError().type() != QDBusError::NoError && interface.lastError().type() != QDBusError::Other ){//There was some error
		if ( message == "PING" )
			emit error(i18n("Could not ping Skype.\nMaybe Skype not running.\nError while sending a message to Skype (%1).", QDBusError::errorString(interface.lastError().type())));//say there was the error
		else
			emit error(i18n("Error while sending a message to Skype (%1).", QDBusError::errorString(interface.lastError().type())));//say there was the error
		if (d->fase != cfConnected)
			emit connectionDone(seUnknown, 0);//Connection attempt finished with error
		disconnectSkype(crLost);//lost the connection
		return QString();//this is enough, no more errors please..
	}

	if ( message == "PING" && reply.value() != "PONG" ){
		emit error(i18n("Could not ping Skype.\nYou are logged out from Skype, please log in."));
		emit connectionDone(seNoSkype, 0);
		disconnectSkype(crLost);//lost the connection
		return QString();//this is enough, no more errors please..
	}

	kDebug(SKYPE_DEBUG_GLOBAL) << "Reply message:" << reply.value();//show what we have received
	return reply.value();//ok, just return it
}
void SkypeConnection::parseMessage(const QString &message) {
	kDebug(SKYPE_DEBUG_GLOBAL);

	switch (d->fase) {
		case cfNameSent: {

			if (message == "OK") {//Accepted by skype
				d->fase = cfProtocolSent;//Sending the protocol
				send(QString("PROTOCOL %1").arg(d->protocolVer));//send the protocol version
			} else {//Not accepted by skype
				emit error(i18n("Skype did not accept this application"));//say there is an error
				emit connectionDone(seAuthorization, 0);//Problem with authorization
				disconnectSkype(crLost);//Lost the connection
			}
			break;
		}
		case cfProtocolSent: {
			if (message.contains(QString("PROTOCOL"), Qt::CaseSensitivity(false))) {//This one inform us what protocol do we use
				bool ok;
				int version = message.section(' ', 1, 1).trimmed().toInt(&ok, 0);//take out the protocol version and make it int
				if (!ok) {
					emit error(i18n("Skype API syntax error"));
					emit connectionDone(seUnknown, 0);
					disconnectSkype(crLost);//lost the connection
					return;//I have enough
				}
				d->protocolVer = version;//this will be the used version of protocol
				d->fase = cfConnected;
				emit connectionDone(seSuccess, version);//tell him that we are connected at last
			} else {//the API is not ready yet, try later
				emit error(i18n("Skype API not ready yet, wait a bit longer"));
				emit connectionDone(seUnknown, 0);
				disconnectSkype(crLost);
				return;
			}
			break;//Other messages are ignored, waiting for the protocol response
		}
		case cfNotConnected: {
			//Why we get message, when we are not connected?
			//Disconnect again
			emit connectionDone(seUnknown, 0);
			disconnectSkype(crLost);
			break;
		}
		case cfWaitingStart: {
			//Ignore this
			break;
		}
		case cfConnected: {
			//We dont need doing with message, it is handled by signal received
			break;
		}
	}
}
void SkypeConnection::connectSkype(const QString &start, const QString &appName, int protocolVer, int bus, bool startDBus, int launchTimeout, int waitBeforeConnect) {
	kdDebug(14311) << k_funcinfo << endl;//some debug info

	if (d->fase != cfNotConnected)
		return;

	d->appName = appName;
	d->protocolVer = protocolVer;

	if (bus == 0)
		d->conn = new DBusQt::Connection(DBUS_BUS_SESSION, this);
	else
		d->conn = new DBusQt::Connection(DBUS_BUS_SYSTEM, this);

	if ((!d->conn) || (!d->conn->isConnected())) {
		if ((bus == 0) && (startDBus)) {
			KProcess bus_launch;
			bus_launch << "dbus_launch";
			bus_launch << "--exit-with-session";
			connect(&bus_launch, SIGNAL(receivedStdout(KProcess *, char *, int)), this, SLOT(setEnv(KProcess *, char*, int )));
			bus_launch.start(KProcess::Block, KProcess::Stdout);
			connectSkype(start, appName, protocolVer, bus, false, launchTimeout, waitBeforeConnect);//try it once again, but if the dbus start did not work, it won't work that time ether, so do not cycle
			return;
		}
		emit error(i18n("Could not connect to DBus"));
		disconnectSkype(crLost);
		emit connectionDone(seNoDBus, 0);
		return;
	}
SkypeConnection::~SkypeConnection() {
	kDebug(SKYPE_DEBUG_GLOBAL);

	disconnectSkype();//disconnect before you leave
	if ( d->skypeProcess.state() != QProcess::NotRunning )//if we started skype process kill it
		d->skypeProcess.kill();
	//QProcess::execute("bash -c \"pkill -2 -U $USER -x ^skype.*$\"");//try find skype process (skype, skype.real, ...) and kill it if we dont start skype or use skype.real wrapper
	//QProcess::execute("bash -c \"pkill -2 -U $USER -x skype\"");
	delete d;//Remove the D pointer
}
void SkypeConnection::parseMessage(const QString &message) {
	kdDebug(14311) << k_funcinfo << QString("(message: %1)").arg(message) << endl;//some debug info

	switch (d->fase) {
		case cfNameSent: {

			if (message == "OK") {//Accepted by skype
				d->fase = cfProtocolSent;//Sending the protocol
				send(QString("PROTOCOL %1").arg(d->protocolVer));//send the protocol version
			} else {//Not accepted by skype
				emit error(i18n("Skype did not accept this application"));//say there is an error
				emit connectionDone(seAuthorization, 0);//Problem with authorization
				disconnectSkype(crLost);//Lost the connection
			}
			break;
		}
		case cfProtocolSent: {
			if (message.contains("PROTOCOL", false)) {//This one inform us what protocol do we use
				bool ok;
				int version = message.section(' ', 1, 1).stripWhiteSpace().toInt(&ok, 0);//take out the protocol version and make it int
				if (!ok) {
					emit error(i18n("Skype API syntax error"));
					emit connectionDone(seUnknown, 0);
					disconnectSkype(crLost);//lost the connection
					return;//I have enough
				}
				d->protocolVer = version;//this will be the used version of protocol
				d->fase = cfConnected;
				emit connectionDone(seSuccess, version);//tell him that we are connected at last
			} else {//the API is not ready yet, try later
				emit error(i18n("Skype API not ready yet, wait a bit longer"));
				emit connectionDone(seUnknown, 0);
				disconnectSkype(crLost);
				return;
			}
			break;//Other messages are ignored, waiting for the protocol response
		}
	}
}
void SkypeConnection::startLogOn() {
	kDebug(SKYPE_DEBUG_GLOBAL);

	if (d->startTimer) {
		d->startTimer->deleteLater();
		d->startTimer = 0L;
	}

	QDBusReply <QString> reply = QDBusInterface("com.Skype.API", "/com/Skype", "com.Skype.API", BUS).call("Invoke", "PING");

	if ( reply.value() != "PONG" ){
		emit error(i18n("Could not ping Skype"));
		disconnectSkype(crLost);
		emit connectionDone(seNoSkype, 0);
		return;
	}

	d->fase = cfNameSent;
	send(QString("NAME %1").arg(d->appName));
}
void SkypeConnection::startLogOn() {
	kdDebug(14311) << k_funcinfo << endl;//some debug info

	if (d->startTimer) {
		d->startTimer->deleteLater();
		d->startTimer = 0L;
	}

	DBusQt::Message ping("com.Skype.API", "/com/Skype", "com.Skype.API", "Ping");//create a ping message
	ping.setAutoActivation(true);
	DBusQt::Message reply = d->conn->sendWithReplyAndBlock(ping);//send it there

	DBusQt::Message::iterator it = reply.begin();
	if (it == reply.end()) {
		emit error(i18n("Could not ping Skype"));
		disconnectSkype(crLost);
		emit connectionDone(seNoSkype, 0);
		return;
	}

	d->fase = cfNameSent;
	send(QString("NAME %1").arg(d->appName));
}
void SkypeConnection::tryConnect() {
	kDebug(SKYPE_DEBUG_GLOBAL);

	{
		QDBusInterface interface("com.Skype.API", "/com/Skype", "com.Skype.API", BUS);
		QDBusReply <QString> reply = interface.call("Invoke", "PING");

		bool started = interface.isValid();
		bool loggedin = reply.value() == "PONG";

		if ( ! started || ! loggedin ){
			if (--d->timeRemaining == 0) {
				d->startTimer->stop();
				d->startTimer->deleteLater();
				d->startTimer = 0L;
				if ( !started )
					emit error(i18n("Could not find Skype.\nYou need to install the original dynamic linked Skype version 2.0 binary from http://www.skype.com"));
				else
					emit error(i18n("Please login to Skype first"));
				disconnectSkype(crLost);
				emit connectionDone(seNoSkype, 0);
				return;
			}
			return;//Maybe next time
		}
	}

	d->startTimer->stop();
	d->startTimer->deleteLater();
	d->startTimer = 0L;
	if (d->waitBeforeConnect) {
		QTimer::singleShot(1000 * d->waitBeforeConnect, this, SLOT(startLogOn()));
		//Skype does not like being bothered right after it's start, give it a while to breathe
	} else
		startLogOn();//OK, it's your choise
}
SkypeConnection::~SkypeConnection() {
	kdDebug(14311) << k_funcinfo << endl;//some debug info

	disconnectSkype();//disconnect before you leave
	delete d;//Remove the D pointer
}
void SkypeConnection::connectSkype(const QString &start, const QString &appName, int protocolVer, int bus, int launchTimeout, int waitBeforeConnect, const QString &name, const QString &pass) {
	kDebug(SKYPE_DEBUG_GLOBAL);

	if (d->fase != cfNotConnected)
		return;

	d->appName = appName;
	d->protocolVer = protocolVer;
	d->bus = bus;

        new ClientAdaptor(this);
	QDBusConnection busConn = BUS;
	bool registred = busConn.registerObject("/com/Skype/Client", this); //Register skype client to dbus for receiving messages to slot Notify

	if ( ! registred ) {
		kDebug(SKYPE_DEBUG_GLOBAL) << "Cant register Skype communication for Kopete on D-Bus";
		emit error(i18n("Cannot register Skype communication for Kopete on D-Bus"));
		return;
	}

	{
		QDBusInterface interface("com.Skype.API", "/com/Skype", "com.Skype.API", BUS);
		QDBusReply <QString> reply = interface.call("Invoke", "PING");

		bool started = interface.isValid();
		bool loggedin = reply.value() == "PONG";

		if ( ! started || ! loggedin ){
			if ( ! started && ! start.isEmpty() ) {//try starting Skype by the given command
				QStringList args = start.split(' ');
				QString skypeBin = args.takeFirst();
				if ( !name.isEmpty() && !pass.isEmpty() ){
					args << "--pipelogin";
				}
				kDebug(SKYPE_DEBUG_GLOBAL) << "Starting skype process" << skypeBin << "with parms" << args;
				d->skypeProcess.start(skypeBin, args);
				if ( !name.isEmpty() && !pass.isEmpty() ){
					kDebug(SKYPE_DEBUG_GLOBAL) << "Sending login name:" << name;
					d->skypeProcess.write(name.trimmed().toLocal8Bit());
					d->skypeProcess.write(" ");
					kDebug(SKYPE_DEBUG_GLOBAL) << "Sending password";
					d->skypeProcess.write(pass.trimmed().toLocal8Bit());
					d->skypeProcess.closeWriteChannel();
				}
				d->skypeProcess.waitForStarted();
				kDebug(SKYPE_DEBUG_GLOBAL) << "Skype process state:" << d->skypeProcess.state() << "Skype process error:" << d->skypeProcess.error();
				if ( d->skypeProcess.state() != QProcess::Running || d->skypeProcess.error() == QProcess::FailedToStart ) {
					emit error(i18n("Could not launch Skype.\nYou need to install the original dynamic linked Skype version 2.0 binary from http://www.skype.com"));
					disconnectSkype(crLost);
					emit connectionDone(seNoSkype, 0);
					return;
				}
			} else {
				if ( start.isEmpty() ){
					emit error(i18n("Could not find Skype.\nYou need to install the original dynamic linked Skype version 2.0 binary from http://www.skype.com"));
					disconnectSkype(crLost);
					emit connectionDone(seNoSkype, 0);
					return;
				}
			}
			d->fase = cfWaitingStart;
			d->startTimer = new QTimer();
			connect(d->startTimer, SIGNAL(timeout()), this, SLOT(tryConnect()));
			d->startTimer->start(1000);
			d->timeRemaining = launchTimeout;
			d->waitBeforeConnect = waitBeforeConnect;
			return;
		}
	}

	startLogOn();
}