/**
 * A class that contains examples of missing values.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class MissingValues {
    /**
     * A method to hold the fragments.
     *
     * @param args  The command line arguments
     */
    public static void main(String[] args) {
//[declarations
        double  value;
        Double  wrapper;
//]declarations        

        value = 0.0;
        wrapper = null;

//[box
        wrapper = value;
//]box

//[expandedbox
        wrapper = Double.valueOf(value);
//]expandedbox

//[unbox
        value = wrapper;
//]unbox

//[expandedunbox
        value = wrapper.doubleValue();
//]expandedunbox
    }

    /**
     * A method that calculates the total, ignoring missing values.
     *
     * @param data  The data
     * @return The total
     */
    public static double ignoreMissing(Double[] data) {
        double average, total;
        int    n;
        
//[ignoremissing
        total = 0.0;
        n     = 0;
        for (int i = 0; i < data.length; i++) {
            if (data[i] != null) {
                total += data[i].doubleValue();
                n++;
            }
        }
        average = total / (double) n;
//]ignoremissing
        return average;
    }

    /**
     * A method that calculates the total, using a default for missing values.
     *
     * @param data  The data
     * @return The total
     */
    public static double defaultMissing(Double[] data) {
        double average, defaultValue, total;

        defaultValue = 0.0;
//[defaultmissing
        total = 0.0;
        for (int i = 0; i < data.length; i++) {
            if (data[i] == null) {
                total += defaultValue; // Initialized elsewhere
            } else {
                total += data[i].doubleValue();
            }
        }
        average = total / (double) data.length;
//]defaultmissing
        return average;
    }

    /**
     * A method that calculates the total, propagating missing values.
     *
     * @param data  The data
     * @return The total
     */
    public static Double propagateMissing(Double[] data) {
        boolean missing;        
        Double  result;
        double  total;
        
//[propagatemissing
        missing = false;        
        total = 0.0;
        for (int i = 0; i < data.length; i++) {
            if (data[i] == null) {
                missing = true;
                break; // No reason to continue iterating
            } else {
                total += data[i].doubleValue();
            }
        }

        if (missing) {
            result = null;
        } else {
            result = Double.valueOf(total / (double) data.length);
        }
//]propagatemissing
        return result;
    }
}

