code: def create_custom_trees(cls, obj, options=None):
          
          clones, id_mapping = {}, []
          obj_ids = cls.get_object_ids(obj)
          offset = cls.id_offset()
          obj_ids = [None] if len(obj_ids)==0 else obj_ids
          for tree_id in obj_ids:
              if tree_id is not None and tree_id in Store.custom_options():
                  original = Store.custom_options()[tree_id]
                  clone = OptionTree(items = original.items(),
                                     groups = original.groups)
                  clones[tree_id + offset + 1] = clone
                  id_mapping.append((tree_id, tree_id + offset + 1))
              else:
                  clone = OptionTree(groups=Store.options().groups)
                  clones[offset] = clone
                  id_mapping.append((tree_id, offset))
  
             # Nodes needed to ensure allowed_keywords is respected
              for k in Store.options():
                  if k in [(opt.split('.')[0],) for opt in options]:
                      group = {grp:Options(
                          allowed_keywords=opt.allowed_keywords)
                               for (grp, opt) in
                               Store.options()[k].groups.items()}
                      clone[k] = group
  
          return {k:cls.apply_customizations(options, t) if options else t
                  for k,t in clones.items()}, id_mapping
docs: Returns the appropriate set of customized subtree clones for
          an object, suitable for merging with Store.custom_options (i.e
          with the ids appropriately offset). Note if an object has no
          integer ids a new OptionTree is built.
  
          The id_mapping return value is a list mapping the ids that
          need to be matched as set to their new values.