/**
          * Generates statistics (used for splitting) based on the
          * current position in the tree (as defined by an
          * attribute mask).
          *
          * @return A Vector that contains the available attributes.
          *         Each attribute's internal statistics array is
          *         populated with appropriate data.  The supplied
          *         stats array is filled with counts of the number of
          *         examples that fall into each of the target classes
          *         at the current position in the tree.
          */
        public List<Attribute> generateStats(AttributeMask mask, int[] stats)
        {
            // First, we fill the stats array - this is not the
            // most efficient approach, since we're looping through
            // the data several times.
            getExampleCounts(mask, DatasetUse.getTrainingExamples(), stats, null);

            // Now, we have to go through the attribute mask
            // and locate the attributes that are still available.
            List<Attribute> results = new List<Attribute>();

            // Create a new mask that we can modify.
            AttributeMask newMask = new AttributeMask(mask);

            // We don't use position 0, that's where the target attribute is.
            for (int i = 1; i < mask.getNumAttributes(); i++)
            {
                if (newMask.isMasked(i) == AttributeMask.UNUSED)
                {
                    // This attribute is available, so we calculate stats for it.
                    Attribute att = null;

                    try
                    {
                        att = DatasetUse.getAttributeByNum(i);
                    }
                    catch (Exception e)
                    {
                        // This can't happen!!
                        return null;
                    }

                    int[][] attStats = att.getStatsArray();

                    // Modify the mask and fill in the arrays.
                    for (int j = 0; j < att.getNumValues(); j++)
                    {
                        newMask.mask(i, j);
                        getExampleCounts(newMask, DatasetUse.getTrainingExamples(), attStats[j], null);
                    }

                    // Reset the mask.
                    newMask.unmask(i);
                    results.Add(att);
                }
            }

            return results;
        }