public Instances transform(Instances train) throws Exception{

    Attribute classAttribute = (Attribute) train.classAttribute().copy();
    Attribute bagLabel = (Attribute) train.attribute(0);
    double labelValue;

    Instances newData = train.attribute(1).relation().stringFreeStructure();

    //insert a bag label attribute at the begining
    newData.insertAttributeAt(bagLabel, 0);

    //insert a class attribute at the end
    newData.insertAttributeAt(classAttribute, newData.numAttributes());
    newData.setClassIndex(newData.numAttributes()-1);

    Instances mini_data = newData.stringFreeStructure();
    Instances max_data = newData.stringFreeStructure();

    Instance newInst = new DenseInstance(newData.numAttributes()); 
    Instance mini_Inst = new DenseInstance(mini_data.numAttributes());
    Instance max_Inst = new DenseInstance(max_data.numAttributes());
    newInst.setDataset(newData);
    mini_Inst.setDataset(mini_data);
    max_Inst.setDataset(max_data);

    double N= train.numInstances( );//number of bags   
    for(int i=0; i<N; i++){	
      int attIdx =1;
      Instance bag = train.instance(i); //retrieve the bag instance
      labelValue= bag.value(0);
      if (m_TransformMethod != TRANSFORMMETHOD_MINIMAX)	    
        newInst.setValue(0, labelValue);
      else {
        mini_Inst.setValue(0, labelValue);
        max_Inst.setValue(0, labelValue);
      }

      Instances data = bag.relationalValue(1); // retrieve relational value for each bag 
      for(int j=0; j<data.numAttributes( ); j++){ 	
        double value;
        if(m_TransformMethod == TRANSFORMMETHOD_ARITHMETIC){
          value = data.meanOrMode(j); 
          newInst.setValue(attIdx++, value);
        }
        else if (m_TransformMethod == TRANSFORMMETHOD_GEOMETRIC){
          double[] minimax = minimax(data, j);
          value = (minimax[0]+minimax[1])/2.0;
          newInst.setValue(attIdx++, value);
        }
        else {  //m_TransformMethod == TRANSFORMMETHOD_MINIMAX
          double[] minimax = minimax(data, j);
          mini_Inst.setValue(attIdx, minimax[0]);//minima value
          max_Inst.setValue(attIdx, minimax[1]);//maxima value
          attIdx++;
        }
      }

      if (m_TransformMethod == TRANSFORMMETHOD_MINIMAX) {
        if (!bag.classIsMissing())
          max_Inst.setClassValue(bag.classValue()); //set class value
        mini_data.add(mini_Inst); 
        max_data.add(max_Inst);
      }
      else{
        if (!bag.classIsMissing())
          newInst.setClassValue(bag.classValue()); //set class value
        newData.add(newInst);		
      }  
    }

    if (m_TransformMethod == TRANSFORMMETHOD_MINIMAX) {
      mini_data.setClassIndex(-1);
      mini_data.deleteAttributeAt(mini_data.numAttributes()-1); //delete class attribute for the minima data
      max_data.deleteAttributeAt(0); // delete the bag label attribute for the maxima data

      newData = Instances.mergeInstances(mini_data, max_data); //merge minima and maxima data
      newData.setClassIndex(newData.numAttributes()-1);

    }	

    return newData;
  }