protected function doTransform(Matrix $mA, $extra = null)
    {
        $this->assertMatrixIsComplete($mA);

        //simple cases
        if ($mA->is('empty') || $mA->is('singleitem') || $mA->is('columnvector')) {
            return clone $mA;
        }

        $numShifts = (is_null($extra) ? 1 : intval($extra)); 
        if (0 == $numShifts) {
            return clone $mA;
        }
        
        //let's process the matrix
        $direction = ($numShifts < 0 ? -1 : 1);
        $nCols = $mA->columns();
        $fSlice = new Colslice();
        $fConc = new Concatenate();
        $fReflect = new Reflect();
        $ret = ($direction == 1 ? clone $mA : $fReflect($mA, Reflect::REFL_Y));

        for ($x = abs($numShifts); $x--; $x==0) {
            $ret = $fConc($fSlice($ret, [$nCols, 1]), $fSlice($ret, [1, $nCols - 1]));
        }    
        
        return ($direction == 1 ? $ret : $fReflect($ret, Reflect::REFL_Y));
    }