text: import shelve
  from settings import *
  
  
  class Element:
      """Base class for all elements containing subelements"""
      def __init__(self, subelems):
          self.subelems = subelems
  
      def find(self, str):
          """Return all lowest level elements containing str"""
          result = []
          for subelem in self.subelems:
              result += subelem.find(str)
          return result
  
  
  class Organizer(Element):
      """Organizer, contains boxes"""
      def __init__(self):
          data = self.__load()
          if data is None:
              data = self.__parse_config()
          super().__init__(data[0])
          self.w = data[1]
          self.h = data[2]
  
      def save(self):
          """Save the organizer and its content to disk"""
          with shelve.open(ORGANIZER_DB) as db:
              db['organizer'] = (self.subelems, self.w, self.h)
      
      def __load(self):
          """Load the organizer and its content from disk"""
          data = None
          try:
              with shelve.open(ORGANIZER_DB) as db:
                  data = db['organizer']
          except FileNotFoundError:
              pass
          return data
  
      def __parse_config(self):
          """Parse the organizer structure from config file"""
          boxes = []
          w = 0
          h = 0
          symbols = {}
          layout = []
          # read conf file
          with open(ORGANIZER_CONF) as conf:
              lines = conf.read().splitlines()
          # parse drawer count and box layout to symbol dict and layout array
          for line in lines:
              if (len(line) > 2 and line[0] != '#'):
                  if (':' in line):
                      s = line.split(':')
                      symbols[s[0]] = s[1]
                  else:
                      layout.append(line.split(' '))
                      w = max(w, len(layout[-1]))
                      h += 1
          # create boxes from layout
          org_w = len(layout[0])
          org_h = len(layout)
          for i, line in enumerate(layout):
              j = 0
              while j < org_w:
                  s = c = line[j]
                  if (c == ''):
                      j += 1
                  else:
                      w = 0
                      h = 0
                      x = j
                      # create correct amount of drawers depending on symbol
                      drawers = []
                      for k in range(int(symbols[s])):
                          drawers.append(Drawer([]))
                      # determine box width
                      while (c == s and j < org_w):
                          j += 1
                          w += 1
                          if (j < org_w):
                              c = line[j]
                      # determine box height and flag array entries to be ignored
                      c = s
                      while (c == s and i + h < org_h):
                          for k in range(w):
                              layout[i + h][x + k] = ''
                          h += 1
                          if (i + h < org_h):
                              c = layout[i + h][x]
                      boxes.append(Box(drawers, x, org_h - i - h, w, h))
          return (boxes, org_w, org_h)
  
  
  class Box(Element):
      """Box, contains drawers"""
      def __init__(self, drawers, x, y, w, h):
          super().__init__(drawers)
          self.x = x
          self.y = y
          self.w = w
          self.h = h
  
  
  class Drawer(Element):
      """Drawer, can countain multiple Items"""
      def __init__(self, items=[]):
          super().__init__(items)
  
  
  class Item:
      """Item, has a name and can have an amount"""
      def __init__(self, name, amount=None):
          self.name = name
          self.amount = amount
          self.lower = self.name.lower()
      
      def find(self, str):
          """Return [self] if all elems of str is contained in name, else []"""
          for s in str:
              if not s in self.lower:
                  return []
          return [self]
  