From f858a761e115ee20b8c5102da8bfead2dde8ffcf Mon Sep 17 00:00:00 2001
From: Mateusz Piekos <mateuszpiekos@gmail.com>
Date: Wed, 11 Jul 2012 14:34:21 +0200
Subject: Tidied up WhitebaordClientTest code


diff --git a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp
index 0707e11..3f90586 100644
--- a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp
+++ b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp
@@ -17,234 +17,290 @@ using namespace Swift;
 
 class WhiteboardClientTest : public CppUnit::TestFixture {
 	CPPUNIT_TEST_SUITE(WhiteboardClientTest);
+	CPPUNIT_TEST(testSynchronize_simplestSync);
+	CPPUNIT_TEST(testSynchronize_withoutTranslation);
 	CPPUNIT_TEST(testSynchronize_nonInterrupted);
 	CPPUNIT_TEST(testSynchronize_clientInterruption);
 	CPPUNIT_TEST(testSynchronize_serverInterruption);
 	CPPUNIT_TEST_SUITE_END();
 public:
-	void testSynchronize_nonInterrupted() {
+
+	/*!
+	 *  /\
+	 *  \/
+	 *   \
+	 */
+	void testSynchronize_simplestSync() {
 		WhiteboardClient client;
 		WhiteboardInsertOperation::ref serverOp;
-		serverOp = createInsertOperation("0", "");
-		serverOp->setPos(0);
+		serverOp = createInsertOperation("0", "", 0);
 		std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> pairResult = client.handleServerOperationReceived(serverOp);
 		CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first));
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
 		WhiteboardInsertOperation::ref clientOp;
-		clientOp = createInsertOperation("a", "0");
-		clientOp->setPos(1);
+		clientOp = createInsertOperation("a", "0", 1);
 		clientOp->setOrigin(WhiteboardOperation::Local);
 		WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		clientOp->setElement(aElement);
-		WhiteboardInsertOperation::ref result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(client.handleLocalOperationReceived(clientOp));
-		CPPUNIT_ASSERT_EQUAL(clientOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(result));
-		CPPUNIT_ASSERT_EQUAL(aElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
+		WhiteboardInsertOperation::ref result;
+		checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement);
+
+		serverOp = createInsertOperation("b", "0", 1);
+		serverOp->setOrigin(WhiteboardOperation::Other);
+		WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
+		serverOp->setElement(bElement);
+		pairResult = client.handleServerOperationReceived(serverOp);
+		checkOperation(pairResult.first, "b", "a", 2, bElement);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
+
+		serverOp = createInsertOperation("a", "b", 1);
+		serverOp->setOrigin(WhiteboardOperation::Other);
+		pairResult = client.handleServerOperationReceived(serverOp);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
+
+		clientOp = createInsertOperation("c", "b", 3);
+		clientOp->setOrigin(WhiteboardOperation::Local);
+		WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
+		clientOp->setElement(cElement);
+		checkOperation(client.handleLocalOperationReceived(clientOp), "c", "a", 3, cElement);
 
+		clientOp = createInsertOperation("c", "a", 1);
+		clientOp->setOrigin(WhiteboardOperation::Local);
+		clientOp->setElement(cElement);
+		pairResult = client.handleServerOperationReceived(clientOp);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
+	}
+
+	/*!
+	 *    /
+	 *   /
+	 *   \
+	 */
+	void testSynchronize_withoutTranslation() {
+		WhiteboardClient client;
+		WhiteboardInsertOperation::ref serverOp;
+		serverOp = createInsertOperation("0", "", 0);
+		std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> pairResult = client.handleServerOperationReceived(serverOp);
+		CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first));
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
+
+		WhiteboardInsertOperation::ref clientOp = createInsertOperation("c", "0", 1);
+		clientOp->setOrigin(WhiteboardOperation::Local);
+		WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
+		clientOp->setElement(cElement);
+		checkOperation(client.handleLocalOperationReceived(clientOp), "c", "0", 1, cElement);
 
-		clientOp = createInsertOperation("b", "a");
-		clientOp->setPos(2);
+		clientOp = createInsertOperation("d", "c", 2);
+		clientOp->setOrigin(WhiteboardOperation::Local);
+		WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
+		clientOp->setElement(dElement);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp));
+
+		clientOp = createInsertOperation("c", "0", 1);
+		clientOp->setOrigin(WhiteboardOperation::Local);
+		clientOp->setElement(cElement);
+		pairResult = client.handleServerOperationReceived(clientOp);
+		checkOperation(pairResult.second, "d", "c", 2, dElement);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
+
+		clientOp = createInsertOperation("d", "c", 3);
+		clientOp->setOrigin(WhiteboardOperation::Local);
+		clientOp->setElement(dElement);
+		pairResult = client.handleServerOperationReceived(clientOp);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
+
+		serverOp = createInsertOperation("e", "d", 4);
+		WhiteboardEllipseElement::ref eElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
+		serverOp->setElement(eElement);
+		pairResult = client.handleServerOperationReceived(serverOp);
+		WhiteboardInsertOperation::ref result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first);
+		CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first));
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
+	}
+
+	/*!
+	 *     /\
+	 *    /  \
+	 *    \  /
+	 *     \/
+	 */
+	void testSynchronize_nonInterrupted() {
+		WhiteboardClient client;
+		WhiteboardInsertOperation::ref serverOp;
+		serverOp = createInsertOperation("0", "", 0);
+		std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> pairResult = client.handleServerOperationReceived(serverOp);
+		CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first));
+		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
+
+		WhiteboardInsertOperation::ref clientOp;
+		clientOp = createInsertOperation("a", "0", 1);
+		clientOp->setOrigin(WhiteboardOperation::Local);
+		WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
+		clientOp->setElement(aElement);
+		checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement);
+
+		clientOp = createInsertOperation("b", "a", 2);
 		clientOp->setOrigin(WhiteboardOperation::Local);
 		WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		clientOp->setElement(bElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp));
 
-		serverOp = createInsertOperation("c", "0");
-		serverOp->setPos(1);
+		serverOp = createInsertOperation("c", "0", 1);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		serverOp->setElement(cElement);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(3, result->getPos());
-		CPPUNIT_ASSERT_EQUAL(cElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getParentID());
+		checkOperation(pairResult.first, "c", "b", 3, cElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
-		serverOp = createInsertOperation("d", "c");
-		serverOp->setPos(2);
+		serverOp = createInsertOperation("d", "c", 2);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		serverOp->setElement(dElement);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(4, result->getPos());
-		CPPUNIT_ASSERT_EQUAL(dElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("c"), result->getParentID());
+		checkOperation(pairResult.first, "d", "c", 4, dElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
-		serverOp = createInsertOperation("a", "d");
-		serverOp->setPos(1);
+		serverOp = createInsertOperation("a", "d", 1);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.second);
+		checkOperation(pairResult.second, "b", "a", 2, bElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getID());
-		CPPUNIT_ASSERT_EQUAL(bElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("a"), result->getParentID());
-		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin());
 
-		serverOp = createInsertOperation("b", "a");
-		serverOp->setPos(2);
+		serverOp = createInsertOperation("b", "a", 2);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		pairResult = client.handleServerOperationReceived(serverOp);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 	}
 
+	/*!
+	 *     /\
+	 *    /  \
+	 *    \  /
+	 *    / /
+	 *    \/
+	 */
 	void testSynchronize_clientInterruption() {
 		WhiteboardClient client;
 		WhiteboardInsertOperation::ref serverOp;
-		serverOp = createInsertOperation("0", "");
-		serverOp->setPos(0);
+		serverOp = createInsertOperation("0", "", 0);
 		std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> pairResult = client.handleServerOperationReceived(serverOp);
 		CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first));
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
 		WhiteboardInsertOperation::ref clientOp;
-		clientOp = createInsertOperation("a", "0");
-		clientOp->setPos(1);
+		clientOp = createInsertOperation("a", "0", 1);
 		clientOp->setOrigin(WhiteboardOperation::Local);
 		WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		clientOp->setElement(aElement);
-		WhiteboardInsertOperation::ref result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(client.handleLocalOperationReceived(clientOp));
-		CPPUNIT_ASSERT_EQUAL(clientOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(result));
-		CPPUNIT_ASSERT_EQUAL(aElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
+		checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement);
 
-
-		clientOp = createInsertOperation("b", "a");
-		clientOp->setPos(2);
+		clientOp = createInsertOperation("b", "a", 2);
 		clientOp->setOrigin(WhiteboardOperation::Local);
 		WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		clientOp->setElement(bElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp));
 
-		serverOp = createInsertOperation("c", "0");
-		serverOp->setPos(1);
+		serverOp = createInsertOperation("c", "0", 1);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		serverOp->setElement(cElement);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(3, result->getPos());
-		CPPUNIT_ASSERT_EQUAL(cElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getParentID());
+		checkOperation(pairResult.first, "c", "b", 3, cElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
-		clientOp = createInsertOperation("e", "a");
-		clientOp->setPos(4);
+		clientOp = createInsertOperation("e", "a", 4);
 		clientOp->setOrigin(WhiteboardOperation::Local);
 		WhiteboardEllipseElement::ref eElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		clientOp->setElement(eElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp));
 
-		serverOp = createInsertOperation("d", "c");
-		serverOp->setPos(2);
+		serverOp = createInsertOperation("d", "c", 2);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		serverOp->setElement(dElement);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(5, result->getPos());
-		CPPUNIT_ASSERT_EQUAL(dElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("e"), result->getParentID());
+		checkOperation(pairResult.first, "d", "e", 5, dElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
-		serverOp = createInsertOperation("a", "d");
-		serverOp->setPos(1);
+		serverOp = createInsertOperation("a", "d", 1);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.second);
+		checkOperation(pairResult.second, "b", "a", 2, bElement);
+//		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin());
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getID());
-		CPPUNIT_ASSERT_EQUAL(bElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("a"), result->getParentID());
-		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin());
 
-		serverOp = createInsertOperation("b", "a");
-		serverOp->setPos(2);
+		serverOp = createInsertOperation("b", "a", 2);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.second);
+		checkOperation(pairResult.second, "e", "b", 4, eElement);
+//		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin());
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(std::string("e"), result->getID());
-		CPPUNIT_ASSERT_EQUAL(eElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getParentID());
-		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin());
 
-		serverOp = createInsertOperation("e", "b");
-		serverOp->setPos(4);
+		serverOp = createInsertOperation("e", "b", 4);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		pairResult = client.handleServerOperationReceived(serverOp);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 	}
 
+	/*!
+	 *    /\
+	 *   / /
+	 *   \ \
+	 *    \/
+	 */
 	void testSynchronize_serverInterruption() {
 		WhiteboardClient client;
 		WhiteboardInsertOperation::ref serverOp;
-		serverOp = createInsertOperation("0", "");
-		serverOp->setPos(0);
+		serverOp = createInsertOperation("0", "", 0);
 		std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> pairResult = client.handleServerOperationReceived(serverOp);
 		CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first));
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
 		WhiteboardInsertOperation::ref clientOp;
-		clientOp = createInsertOperation("a", "0");
-		clientOp->setPos(1);
+		clientOp = createInsertOperation("a", "0", 1);
 		clientOp->setOrigin(WhiteboardOperation::Local);
 		WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		clientOp->setElement(aElement);
-		WhiteboardInsertOperation::ref result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(client.handleLocalOperationReceived(clientOp));
-		CPPUNIT_ASSERT_EQUAL(clientOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(result));
-		CPPUNIT_ASSERT_EQUAL(aElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-
+		checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement);
 
-		clientOp = createInsertOperation("b", "a");
-		clientOp->setPos(2);
+		clientOp = createInsertOperation("b", "a", 2);
 		clientOp->setOrigin(WhiteboardOperation::Local);
 		WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		clientOp->setElement(bElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp));
 
-		serverOp = createInsertOperation("c", "0");
-		serverOp->setPos(1);
+		serverOp = createInsertOperation("c", "0", 1);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		serverOp->setElement(cElement);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(3, result->getPos());
-		CPPUNIT_ASSERT_EQUAL(cElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getParentID());
+		checkOperation(pairResult.first, "c", "b", 3, cElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
-		serverOp = createInsertOperation("a", "c");
-		serverOp->setPos(1);
+		serverOp = createInsertOperation("a", "c", 1);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		serverOp->setElement(aElement);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.second);
+		checkOperation(pairResult.second, "b", "a", 2, bElement);
+//		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin());
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getID());
-		CPPUNIT_ASSERT_EQUAL(bElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("a"), result->getParentID());
-		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin());
 
-		serverOp = createInsertOperation("d", "a");
-		serverOp->setPos(3);
+		serverOp = createInsertOperation("d", "a", 3);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0);
 		serverOp->setElement(dElement);
 		pairResult = client.handleServerOperationReceived(serverOp);
-		result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first);
-		CPPUNIT_ASSERT_EQUAL(4, result->getPos());
-		CPPUNIT_ASSERT_EQUAL(dElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement()));
-		CPPUNIT_ASSERT_EQUAL(std::string("c"), result->getParentID());
+		checkOperation(pairResult.first, "d", "c", 4, dElement);
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 
-		serverOp = createInsertOperation("b", "d");
-		serverOp->setPos(2);
+		serverOp = createInsertOperation("b", "d", 2);
 		serverOp->setElement(bElement);
 		serverOp->setOrigin(WhiteboardOperation::Other);
 		pairResult = client.handleServerOperationReceived(serverOp);
@@ -252,12 +308,25 @@ public:
 		CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second);
 	}
 
-	WhiteboardInsertOperation::ref createInsertOperation(std::string id, std::string parent) {
+	WhiteboardInsertOperation::ref createInsertOperation(std::string id, std::string parent, int pos) {
 		WhiteboardInsertOperation::ref operation = boost::make_shared<WhiteboardInsertOperation>();
 		operation->setParentID(parent);
 		operation->setID(id);
+		operation->setPos(pos);
 		return operation;
 	}
+
+	void checkOperation(WhiteboardOperation::ref operation, std::string id, std::string parent, int pos = -1, WhiteboardElement::ref element = WhiteboardElement::ref()) {
+		CPPUNIT_ASSERT_EQUAL(id, operation->getID());
+		CPPUNIT_ASSERT_EQUAL(parent, operation->getParentID());
+		if (pos != -1) {
+			CPPUNIT_ASSERT_EQUAL(pos, operation->getPos());
+		}
+
+		if (element) {
+			CPPUNIT_ASSERT_EQUAL(element, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation)->getElement());
+		}
+	}
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(WhiteboardClientTest);
diff --git a/Swiften/Whiteboard/WhiteboardClient.cpp b/Swiften/Whiteboard/WhiteboardClient.cpp
index 02ee48d..447e5de 100644
--- a/Swiften/Whiteboard/WhiteboardClient.cpp
+++ b/Swiften/Whiteboard/WhiteboardClient.cpp
@@ -11,39 +11,58 @@
 namespace Swift {
 	WhiteboardOperation::ref WhiteboardClient::handleLocalOperationReceived(WhiteboardOperation::ref operation) {
 		localOperations_.push_back(operation);
+//		if (bridge_.size() > 0) {
+		WhiteboardOperation::ref op = boost::make_shared<WhiteboardInsertOperation>(*boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation).get());
 		if (bridge_.size() > 0) {
-			WhiteboardOperation::ref op = boost::make_shared<WhiteboardInsertOperation>(*boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation).get());
 			op->setParentID(bridge_.back()->getID());
-			bridge_.push_back(op);
 		}
+		bridge_.push_back(op);
+//		}
 		if (lastSentOperationID_.empty())
 		{
+			WhiteboardOperation::ref op = boost::make_shared<WhiteboardInsertOperation>(*boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation).get());
+			if (serverOperations_.size() > 0) {
+				op->setParentID(serverOperations_.back()->getID());
+			}
 			lastSentOperationID_ = operation->getID();
-			return operation;
+			return op;
+		} else {
+			return WhiteboardOperation::ref();
 		}
-		return WhiteboardOperation::ref();
 	}
 
 	std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardClient::handleServerOperationReceived(WhiteboardOperation::ref operation) {
 		serverOperations_.push_back(operation);
 		WhiteboardOperation::ref clientOp;
 		WhiteboardOperation::ref serverOp;
-		if (localOperations_.empty()) {// || localOperations_.back()->getID() == operation->getParentID()) {
+//		if (localOperations_.empty()) {// || localOperations_.back()->getID() == operation->getParentID()) {
+		//Situation where client and server are in sync
+		if (localOperations_.size() == serverOperations_.size()-1) {
 			localOperations_.push_back(operation);
 			clientOp = operation;
 		} else if (lastSentOperationID_ == operation->getID()) {
-			if (lastSentOperationID_ == bridge_.front()->getID()) {
+			//Client received confirmation about own operation and it sends next operation to server
+			if (bridge_.size() > 0 && lastSentOperationID_ == bridge_.front()->getID()) {
 				bridge_.erase(bridge_.begin());
 			}
-			std::list<WhiteboardOperation::ref>::iterator it;
+			/*std::list<WhiteboardOperation::ref>::iterator it;
 			for (it = bridge_.begin(); it != bridge_.end(); ++it) {
 				if ((*it)->getParentID() == lastSentOperationID_) {
 					lastSentOperationID_ = (*it)->getID();
-					//serverOperations_.push_back(*it);
 					serverOp = *it;
 					serverOp->setOrigin(WhiteboardOperation::Other);
 					break;
 				}
+				}*/
+
+			if (bridge_.size() > 0 && (bridge_.front())->getParentID() == lastSentOperationID_) {
+				lastSentOperationID_ = (bridge_.front())->getID();
+				serverOp = bridge_.front();
+				serverOp->setOrigin(WhiteboardOperation::Other);
+			}
+
+			if (!serverOp) {
+				lastSentOperationID_.clear();
 			}
 		} else {
 			if (bridge_.size() > 0 && bridge_.front()->getParentID() == operation->getParentID()) {
@@ -68,6 +87,7 @@ namespace Swift {
 				localOperations_.push_back(temp);
 				clientOp = temp;
 			} else {
+//doesn't get executed
 				std::list<WhiteboardOperation::ref>::reverse_iterator it;
 				std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> opPair;
 				WhiteboardInsertOperation::ref temp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
-- 
cgit v0.10.2-6-g49f6