class WienerKolmogorovEstimator implements IComponentsEstimator {

    @Override
    public DefaultSeriesDecomposition decompose(SeatsModel model, UcarimaModel ucm,
            InformationSet info, SeatsContext context) {
        DefaultSeriesDecomposition decomposition = new DefaultSeriesDecomposition(
                DecompositionMode.Additive);
        BurmanEstimatesC burman = new BurmanEstimatesC();
//	BurmanEstimates burman = new BurmanEstimates();
        UcarimaModel ucmc = ucm.clone();
        ucmc.compact(2, 2);

        TsData s = model.getSeries();
        int nf = nf(s.getFrequency());
        TsDomain fdomain = new TsDomain(s.getEnd(), nf);
        burman.setForecastsCount(nf);

        // check the ucarima model. 
        // ucm=checkModel(ucm);
        if (model.isMeanCorrection()) {
            burman.setUcarimaModelWithMean(ucmc);
        } else {
            burman.setUcarimaModel(ucmc);
        }
        burman.setData(s);
        burman.setSer(model.getSer());
        int ncmps = ucmc.getComponentsCount();

        TsData[] cmps = new TsData[ncmps];
        TsData[] fcmps = new TsData[ncmps];
        TsData[] ecmps = new TsData[ncmps];
        TsData[] efcmps = new TsData[ncmps];

        for (int i = 0; i < ncmps; ++i) {
            if (i == 0 || !ucmc.getComponent(i).isNull()) {
                double[] tmp = burman.estimates(i, true);
                cmps[i] = new TsData(s.getStart(), tmp, false);
                ecmps[i] = new TsData(s.getStart(), burman.stdevEstimates(i), false);
                tmp = burman.forecasts(i, true);
                if (tmp != null) {
                    fcmps[i] = new TsData(s.getEnd(), tmp, false);
                }
                tmp = burman.stdevForecasts(i, true);
                if (tmp != null) {
                    efcmps[i] = new TsData(s.getEnd(), tmp, false);
                }
            }
        }

        TsData fs = new TsData(s.getEnd(), burman.getSeriesForecasts(), false);
        TsData efs = null, efsa = null;
        for (int i = 0; i < efcmps.length; ++i) {
            if (efcmps[i] != null) {
                TsData var = efcmps[i].times(efcmps[i]);
                efs = TsData.add(efs, var);
                if (i != 1) {
                    efsa = TsData.add(efsa, var);
                }

            }
        }

        decomposition.add(s, ComponentType.Series);
        decomposition.add(fs.fittoDomain(fdomain), ComponentType.Series, ComponentInformation.Forecast);
        if (efs != null) {
            decomposition.add(efs.fittoDomain(fdomain).sqrt(), ComponentType.Series, ComponentInformation.StdevForecast);
        }
        if (cmps[0] != null) {
            decomposition.add(cmps[0], ComponentType.Trend);
        }
        if (cmps[1] != null) {
            decomposition.add(cmps[1], ComponentType.Seasonal);
        }

        if (fcmps[0] != null) {
            decomposition.add(fcmps[0].fittoDomain(fdomain), ComponentType.Trend, ComponentInformation.Forecast);
        }
        if (fcmps[1] != null) {
            decomposition.add(fcmps[1].fittoDomain(fdomain), ComponentType.Seasonal, ComponentInformation.Forecast);
        }
        decomposition.add(TsData.subtract(fs, fcmps[1]),
                ComponentType.SeasonallyAdjusted, ComponentInformation.Forecast);
        if (ecmps[0] != null) {
            decomposition.add(ecmps[0], ComponentType.Trend, ComponentInformation.Stdev);
        }
        if (efcmps[0] != null) {
            decomposition.add(efcmps[0], ComponentType.Trend, ComponentInformation.StdevForecast);
        }
        decomposition.add(TsData.subtract(s, cmps[1]),
                ComponentType.SeasonallyAdjusted);
        if (ecmps[1] != null) {
            decomposition.add(ecmps[1], ComponentType.Seasonal, ComponentInformation.Stdev);
            decomposition.add(ecmps[1], ComponentType.SeasonallyAdjusted, ComponentInformation.Stdev);
            decomposition.add(efsa.sqrt(), ComponentType.SeasonallyAdjusted, ComponentInformation.StdevForecast);
        }
        if (efcmps[1] != null) {
            decomposition.add(efcmps[1], ComponentType.Seasonal, ComponentInformation.StdevForecast);
        }
        decomposition.add(cmps[2], ComponentType.Irregular);
        if (fcmps[2] != null) {
            decomposition.add(fcmps[2], ComponentType.Irregular, ComponentInformation.Forecast);
        }
        if (ecmps[2] != null) {
            decomposition.add(ecmps[2], ComponentType.Irregular, ComponentInformation.Stdev);
        }
        if (efcmps[2] != null) {
            decomposition.add(efcmps[2], ComponentType.Irregular, ComponentInformation.StdevForecast);
        }

        return decomposition;
    }

    public  WienerKolmogorovEstimator(int npred);

}