def GBL (cases, layersize, splitting="shorteraxis"):
    """
                            * Guilliotine Bottom Left *

    This algorithm keeps track of all the empty spaces still available. Every time
    a new case is placed in one of these spaces, it is replaced with two new spaces
    breaking down the L-shaped space into two smaller rectangles.

                     Vertical Cutting            Horizontal Cutting
                   ____________________         ____________________
                  |    |               |       |                    |
                  |____|               |       |____________________|
                  |####|               |       |####|               |
                  |####|_______________|       |####|_______________|


    In this particular case priority is given to the spaces closer to the bottom
    left corner.
    """
    X, Y = layersize
    F = [(0, 0, X, Y), ]  # (x, y, sizex, sizey) For each rectangle

    for case in cases:
        # Sort spaces prioritizing those close to the bottom left corner.
        F.sort(key=lambda s: (s[0], s[1]))
        for i in range(len(F)):
            x, y, sizex, sizey = F[i]
            # Check the area as a preliminar control
            if sizex * sizey < case.sizex * case.sizey:
                continue
            # Try to eventually rotate the item if the are fits, but the width
            # and the height not.
            if sizex < case.sizex or sizey < case.sizey:
                case.rotate()
                if sizex < case.sizex or sizey < case.sizey:
                    continue

            # If it fits place the item and remove the space from the set of spaces.
            case.x, case.y = x, y
            F.pop(i)

            # Define the cutting
            if (sizex, sizey) == (case.sizex, case.sizey):
                # No cut needed
                pass
            elif sizey == case.sizey:
                # Just vertical cut possible
                F.append((case.right, y, sizex - case.sizex, sizey))
            elif sizex == case.sizex:
                # Just horizontal cut possible
                F.append((x, case.top, sizex, sizey - case.sizey))
            else:
                # Define if cutting horizontally or vertically depending on the cutting
                # policy.
                if splitting == "shorteraxis":
                    if sizex < sizey:
                        F.extend([(case.right, y, sizex - case.sizex, case.sizey),
                                  (x, case.top, sizex, sizey - case.sizey)])       # Horizontal cutting
                    else:
                        F.extend([(case.right, y, sizex - case.sizex, sizey),
                                  (x, case.top, case.sizex, sizey - case.sizey)])  # Vertical cutting
                elif splitting == "longeraxis":
                    if sizex > sizey:
                        F.extend([(case.right, y, sizex - case.sizex, case.sizey),
                                  (x, case.top, sizex, sizey - case.sizey)])       # Horizontal cutting
                    else:
                        F.extend([(case.right, y, sizex - case.sizex, sizey),
                                  (x, case.top, case.sizex, sizey - case.sizey)])  # Vertical cutting
                elif splitting == "shorterleftover":
                    if sizex - case.sizex < sizey - case.sizey:
                        F.extend([(case.right, y, sizex - case.sizex, case.sizey),
                                  (x, case.top, sizex, sizey - case.sizey)])       # Horizontal cutting
                    else:
                        F.extend([(case.right, y, sizex - case.sizex, sizey),
                                  (x, case.top, case.sizex, sizey - case.sizey)])  # Vertical cutting
                elif splitting == "longerleftover":
                    if sizex - case.sizex > sizey - case.sizey:
                        F.extend([(case.right, y, sizex - case.sizex, case.sizey),
                                  (x, case.top, sizex, sizey - case.sizey)])       # Horizontal cutting
                    else:
                        F.extend([(case.right, y, sizex - case.sizex, sizey),
                                  (x, case.top, case.sizex, sizey - case.sizey)])  # Vertical cutting
                else:
                    raise Exception("Splitting rule not defined.")

            break
        else:
            # If no space is feasible the packing is not possible.
            return False

    return True