@Override
    protected void processChunk() {
        Classifier addedClassifier = null;

        // Compute weights
        double candidateClassifierWeight = this.computeCandidateWeight(
                this.candidateClassifier, this.currentChunk, this.numFolds);

        for (int i = 0; i < this.storedLearners.length; i++) {
            this.storedWeights[i][0] = this.computeWeight(
                    this.storedLearners[(int) this.storedWeights[i][1]], this.currentChunk);
        }

        if (this.storedLearners.length < this.maxStoredCount) {
            // Train and add classifier
            this.trainOnChunk(this.candidateClassifier);
            addedClassifier = this.addToStored(this.candidateClassifier,
                    candidateClassifierWeight);
        } else {
            // Substitute poorest classifier
            java.util.Arrays.sort(this.storedWeights, weightComparator);

            if (this.storedWeights[0][0] < candidateClassifierWeight) {
                this.trainOnChunk(this.candidateClassifier);
                this.storedWeights[0][0] = candidateClassifierWeight;
                addedClassifier = this.candidateClassifier.copy();
                this.storedLearners[(int) this.storedWeights[0][1]] = addedClassifier;
            }
        }

        int ensembleSize = java.lang.Math.min(this.storedLearners.length,
                this.maxMemberCount);
        this.ensemble = new Classifier[ensembleSize];
        this.ensembleWeights = new double[ensembleSize];

        // Sort learners according to their weights
        java.util.Arrays.sort(this.storedWeights, weightComparator);

        double mse_r = this.computeMseR();

        // Select top k classifiers to construct the ensemble
        int storeSize = this.storedLearners.length;
        for (int i = 0; i < ensembleSize; i++) {
            this.ensembleWeights[i] = this.storedWeights[storeSize - i - 1][0];
            this.ensemble[i] = this.storedLearners[(int) this.storedWeights[storeSize
                    - i - 1][1]];

            if (this.ensemble[i] != addedClassifier) {
                if (mse_r > 0 && this.ensembleWeights[i] > 1 / mse_r) {
                    this.trainOnChunk(this.ensemble[i]);
                }
            }
        }

        this.classDistributions = null;
        this.currentChunk = null;
        this.candidateClassifier = (Classifier) getPreparedClassOption(this.learnerOption);
        this.candidateClassifier.resetLearning();
    }