public double[] distributionForInstance(Instance instance) throws Exception {

    //Definition of local variables
    double[] probs = new double[m_NumClasses];
    int sIndex;
    double prob;
    double condiMutualInfoSum;

    // store instance's att values in an int array
    int[] attIndex = new int[m_NumAttributes];
    for(int att = 0; att < m_NumAttributes; att++) {
      if(att == m_ClassIndex)
        attIndex[att] = -1;
      else
        attIndex[att] = m_StartAttIndex[att] + (int)instance.value(att);
    }

    // calculate probabilities for each possible class value
    for(int classVal = 0; classVal < m_NumClasses; classVal++) {
      probs[classVal]=(m_ClassCounts[classVal]+1.0/m_NumClasses)/(m_NumInstances+1.0);
      for(int son = 0; son < m_NumAttributes; son++) {
        if(attIndex[son]==-1) continue;
        sIndex=attIndex[son];
        attIndex[son]=-1;
        prob=0;
        condiMutualInfoSum=0;
        for(int parent=0; parent<m_NumAttributes; parent++) {
          if(attIndex[parent]==-1) continue;
          condiMutualInfoSum+=m_condiMutualInfo[son][parent];
          prob+=m_condiMutualInfo[son][parent]*(m_ClassAttAttCounts[classVal][attIndex[parent]][sIndex]+1.0/m_NumAttValues[son])/(m_ClassAttAttCounts[classVal][attIndex[parent]][attIndex[parent]] + 1.0);
        }
        if(condiMutualInfoSum>0){
          prob=prob/condiMutualInfoSum;
          probs[classVal] *= prob;
        }
        else{
          prob=(m_ClassAttAttCounts[classVal][sIndex][sIndex]+1.0/m_NumAttValues[son])/(m_ClassCounts[classVal]+1.0);
          probs[classVal]*= prob;
        }
        attIndex[son] = sIndex;
      }
    }
    Utils.normalize(probs);
    return probs;
  }