docs: def group(self, meta=None, meta_aggregates=None, regs=None,
                regs_aggregates=None, meta_group_name="_group"):
          """
          *Wrapper of* ``GROUP``
  
          The GROUP operator is used for grouping both regions and/or metadata of input
          dataset samples according to distinct values of certain attributes (known as grouping
          attributes); new grouping attributes are added to samples in the output dataset,
          storing the results of aggregate function evaluations over metadata and/or regions
          in each group of samples.
          Samples having missing values for any of the grouping attributes are discarded.
  
  
          :param meta: (optional) a list of metadata attributes
          :param meta_aggregates: (optional) {'new_attr': fun}
          :param regs: (optional) a list of region fields
          :param regs_aggregates: {'new_attr': fun}
          :param meta_group_name: (optional) the name to give to the group attribute in the
                 metadata
          :return: a new GMQLDataset
  
          Example of usage. We group samples by `antibody` and we aggregate the region pvalues taking the maximum value
          calling the new region field `maxPvalue`::
  
              import gmql as gl
  
              d1 = gl.get_example_dataset("Example_Dataset_1")
              result = d1.group(meta=['antibody'], regs_aggregates={'maxPvalue': gl.MAX("pvalue")})
          """
  
          if isinstance(meta, list) and \
              all([isinstance(x, str) for x in meta]):
              meta = Some(meta)
          elif meta is None:
              meta = none()
          else:
              raise TypeError("meta must be a list of strings. "
                              "{} was provided".format(type(meta)))
          expBuild = self.pmg.getNewExpressionBuilder(self.__index)
          if isinstance(meta_aggregates, dict):
              metaAggregates = []
              for k in meta_aggregates:
                  if isinstance(k, str):
                      item = meta_aggregates[k]
                      if isinstance(item, (SUM, MIN, MAX, AVG, BAG,
                                           BAGD, STD, MEDIAN, COUNTSAMP)):
                          functionName = item.get_aggregate_name()
                          argument = item.get_argument()
                          if argument is None:
                              argument = none()
                          else:
                              argument = Some(argument)
                          metaAggregates.append(expBuild.createMetaAggregateFunction(functionName,
                                                                                     k, argument))
                      else:
                          raise TypeError("the item of the dictionary must be an Aggregate of the following: "
                                          "SUM, MIN, MAX, AVG, BAG, BAGD, STD, COUNTSAMP. "
                                          "{} was provided".format(type(item)))
                  else:
                      raise TypeError("keys of meta_aggregates must be string. "
                                      "{} was provided".format(type(k)))
              metaAggregates = Some(metaAggregates)
          elif meta_aggregates is None:
              metaAggregates = none()
          else:
              raise TypeError("meta_aggregates must be a dictionary of Aggregate functions. "
                              "{} was provided".format(type(meta_aggregates)))
          if isinstance(regs, list) and \
              all([isinstance(x, str) for x in regs]):
              regs = Some(regs)
          elif regs is None:
              regs = none()
          else:
              raise TypeError("regs must be a list of strings. "
                              "{} was provided".format(type(regs)))
  
          if isinstance(regs_aggregates, dict):
              regionAggregates = []
              for k in regs_aggregates.keys():
                  if isinstance(k, str):
                      item = regs_aggregates[k]
                      if isinstance(item, (SUM, MIN, MAX, AVG, BAG, BAGD,
                                           MEDIAN, COUNT)):
                          op_name = item.get_aggregate_name()
                          op_argument = item.get_argument()
                          if op_argument is None:
                              op_argument = none()
                          else:
                              op_argument = Some(op_argument)
                          regsToReg = expBuild.getRegionsToRegion(op_name, k, op_argument)
                          regionAggregates.append(regsToReg)
                      else:
                          raise TypeError("the item of the dictionary must be an Aggregate of the following: "
                                          "SUM, MIN, MAX, AVG, BAG, BAGD, MEDIAN, COUNT. "
                                          "{} was provided".format(type(item)))
                  else:
                      raise TypeError("The key of new_reg_fields must be a string. "
                                      "{} was provided".format(type(k)))
              regionAggregates = Some(regionAggregates)
          elif regs_aggregates is None:
              regionAggregates = none()
          else:
              raise TypeError("new_reg_fields must be a list of dictionary. "
                              "{} was provided".format(type(regs_aggregates)))
  
          if isinstance(meta_group_name, str):
              pass
          else:
              raise TypeError("meta_group_name must be a string. "
                              "{} was provided".format(type(meta_group_name)))
  
          new_index = self.opmng.group(self.__index, meta, metaAggregates, meta_group_name, regs, regionAggregates)
  
          return GMQLDataset(index=new_index, location=self.location,
                             local_sources=self._local_sources,
                             remote_sources=self._remote_sources,
                             meta_profile=self.meta_profile)