private <T> List<Slice> splitArray(final Mass[][] data,final int chunkSize,boolean iteratorNeedsNeighbours) 
    {
    	int horizSize = (int) Math.sqrt( chunkSize );
    	if ( horizSize < 1 ) {
    		horizSize = 1;
    	}
    	
    	final int vertSize = horizSize;
    	
    	final int horizSlices = params.getGridColumnCount() / horizSize;
    	final int vertSlices = params.getGridRowCount() / vertSize;
    	
    	final int horizRest = params.getGridColumnCount() - horizSlices*horizSize;
    	final int vertRest = params.getGridRowCount() - vertSlices*vertSize;
    			
    	final List<Slice> result = new ArrayList<>();
    	
    	final int xEnd = horizSlices*horizSize;
    	final int yEnd = vertSlices*vertSize;
    	
		int x,y;
    	for ( y = 0; y < yEnd ; y+= vertSize ) 
    	{    	
    		final boolean isAtBottomEdge = (y+vertSize) >= yEnd;
	    	for ( x = 0 ; x < xEnd ; x+= horizSize ) 
	    	{
	    		boolean isAtRightEdge = (x+horizRest) >= xEnd;
	    		result.add( new Slice( x , y , horizSize , vertSize , iteratorNeedsNeighbours , isAtRightEdge , isAtBottomEdge ) );
	    	}
	    	if ( horizRest > 0 ) {
	    		result.add( new Slice( x , y , horizRest , vertSize , iteratorNeedsNeighbours , true , isAtBottomEdge  ) );
	    	}
    	}
    	if ( vertRest > 0 ) 
    	{
	    	for ( x = 0 ; x < xEnd ; x+= horizSize ) 
	    	{
	    		boolean isAtRightEdge = (x+horizRest) >= xEnd;
	    		result.add( new Slice( x , y , horizSize , vertRest , iteratorNeedsNeighbours , isAtRightEdge , true ) );
	    	}    
	    	if ( horizRest > 0 ) {
	    		result.add( new Slice( x , y , horizRest , vertRest , iteratorNeedsNeighbours , true , true ) );
	    	}	    	
    	}
    	return result;
    }