public override void TryToMovePuzzlePiece(PuzzlePiece piece, int newXIndex, int newYIndex, Point?p)
        {
            int oldX = piece.XIndex;
            int oldY = piece.YIndex;

            RemovePuzzlePieceFromLevelMatrix(piece);
            piece.XIndex = newXIndex;
            piece.YIndex = newYIndex;

            PuzzlePiece overlapedPiece;

            if (IsPieceInsideOfGrid(piece))
            {
                if (!IsPieceOverlapingWithOthers(piece, out overlapedPiece))
                {
                    piece.IsAdded = true;
                    piece.X       = (piece.XIndex + gridWidth) * CellSize;
                    piece.Y       = (piece.YIndex + gridHeight) * CellSize;
                    AddPuzzlePieceTolLevelMatrix(piece);
                    IsLevelSolved();
                    return;
                }
            }
            else if (IsPieceOutsideOfGrid(piece))
            {
                if (IsPieceInsideOfLevel(piece))
                {
                    if (!IsPieceOverlapingWithOthers(piece, out overlapedPiece))
                    {
                        piece.IsAdded = false;
                        piece.X       = (piece.XIndex + gridWidth) * CellSize;
                        piece.Y       = (piece.YIndex + gridHeight) * CellSize;
                        AddPuzzlePieceTolLevelMatrix(piece);
                        return;
                    }
                    else
                    {
                        //element is trying to be placed over another outside of grid
                        if (GetNumberOfOverlapingPieces(piece) <= 1 &&
                            piece.GetType() != typeof(CombinedPuzzlePiece) &&
                            overlapedPiece.GetType() != typeof(CombinedPuzzlePiece))
                        {
                            //create combined piece
                            CombinedPuzzlePiece newPuzzlePiece = CreateUnionPuzzlePiece(piece, overlapedPiece);

                            //remove dragged piece
                            RemovePuzzlePieceFromLevelMatrix(piece);
                            drawings.Remove(piece);
                            puzzlePieces.Remove(piece);

                            //remove overlaped piece
                            RemovePuzzlePieceFromLevelMatrix(overlapedPiece);
                            drawings.Remove(overlapedPiece);
                            puzzlePieces.Remove(overlapedPiece);

                            //add combined puzzle piece to level
                            newPuzzlePiece.PaintShape(this);
                            drawings.Add(newPuzzlePiece);
                            puzzlePieces.Add(newPuzzlePiece);
                            AddPuzzlePieceTolLevelMatrix(newPuzzlePiece);
                            newPuzzlePiece.isInitialised = true;
                            return;
                        }
                    }
                }
            }

            piece.XIndex = oldX;
            piece.YIndex = oldY;
            AddPuzzlePieceTolLevelMatrix(piece);
        }