Example usage for java.util ListIterator hasPrevious

List of usage examples for java.util ListIterator hasPrevious

Introduction

In this page you can find the example usage for java.util ListIterator hasPrevious.

Prototype

boolean hasPrevious();

Source Link

Document

Returns true if this list iterator has more elements when traversing the list in the reverse direction.

Usage

From source file:com.emc.ecs.sync.target.S3Target.java

@Override
public void filter(SyncObject obj) {
    try {/*  w ww . j  ava 2 s. co m*/
        // skip the root of the bucket since it obviously exists
        if ("".equals(rootKey + obj.getRelativePath())) {
            log.debug("Target is bucket root; skipping");
            return;
        }

        // some sync objects lazy-load their metadata (i.e. AtmosSyncObject)
        // since this may be a timed operation, ensure it loads outside of other timed operations
        if (!(obj instanceof S3ObjectVersion) || !((S3ObjectVersion) obj).isDeleteMarker())
            obj.getMetadata();

        // Compute target key
        String targetKey = getTargetKey(obj);
        obj.setTargetIdentifier(AwsS3Util.fullPath(bucketName, targetKey));

        if (includeVersions) {
            ListIterator<S3ObjectVersion> sourceVersions = s3Source.versionIterator((S3SyncObject) obj);
            ListIterator<S3ObjectVersion> targetVersions = versionIterator(obj);

            boolean newVersions = false, replaceVersions = false;
            if (force) {
                replaceVersions = true;
            } else {

                // special workaround for bug where objects are listed, but they have no versions
                if (sourceVersions.hasNext()) {

                    // check count and etag/delete-marker to compare version chain
                    while (sourceVersions.hasNext()) {
                        S3ObjectVersion sourceVersion = sourceVersions.next();

                        if (targetVersions.hasNext()) {
                            S3ObjectVersion targetVersion = targetVersions.next();

                            if (sourceVersion.isDeleteMarker()) {

                                if (!targetVersion.isDeleteMarker())
                                    replaceVersions = true;
                            } else {

                                if (targetVersion.isDeleteMarker())
                                    replaceVersions = true;

                                else if (!sourceVersion.getETag().equals(targetVersion.getETag()))
                                    replaceVersions = true; // different checksum
                            }

                        } else if (!replaceVersions) { // source has new versions, but existing target versions are ok
                            newVersions = true;
                            sourceVersions.previous(); // back up one
                            putIntermediateVersions(sourceVersions, targetKey); // add any new intermediary versions (current is added below)
                        }
                    }

                    if (targetVersions.hasNext())
                        replaceVersions = true; // target has more versions

                    if (!newVersions && !replaceVersions) {
                        log.info("Source and target versions are the same. Skipping {}", obj.getRelativePath());
                        return;
                    }
                }
            }

            // something's off; must delete all versions of the object
            if (replaceVersions) {
                log.info(
                        "[{}]: version history differs between source and target; re-placing target version history with that from source.",
                        obj.getRelativePath());

                // collect versions in target
                List<DeleteObjectsRequest.KeyVersion> deleteVersions = new ArrayList<>();
                while (targetVersions.hasNext())
                    targetVersions.next(); // move cursor to end
                while (targetVersions.hasPrevious()) { // go in reverse order
                    S3ObjectVersion version = targetVersions.previous();
                    deleteVersions.add(new DeleteObjectsRequest.KeyVersion(targetKey, version.getVersionId()));
                }

                // batch delete all versions in target
                log.debug("[{}]: deleting all versions in target", obj.getRelativePath());
                s3.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(deleteVersions));

                // replay version history in target
                while (sourceVersions.hasPrevious())
                    sourceVersions.previous(); // move cursor to beginning
                putIntermediateVersions(sourceVersions, targetKey);
            }

        } else { // normal sync (no versions)
            Date sourceLastModified = obj.getMetadata().getModificationTime();
            long sourceSize = obj.getMetadata().getContentLength();

            // Get target metadata.
            ObjectMetadata destMeta = null;
            try {
                destMeta = s3.getObjectMetadata(bucketName, targetKey);
            } catch (AmazonS3Exception e) {
                if (e.getStatusCode() != 404)
                    throw new RuntimeException("Failed to check target key '" + targetKey + "' : " + e, e);
            }

            if (!force && obj.getFailureCount() == 0 && destMeta != null) {

                // Check overwrite
                Date destLastModified = destMeta.getLastModified();
                long destSize = destMeta.getContentLength();

                if (destLastModified.equals(sourceLastModified) && sourceSize == destSize) {
                    log.info("Source and target the same.  Skipping {}", obj.getRelativePath());
                    return;
                }
                if (destLastModified.after(sourceLastModified)) {
                    log.info("Target newer than source.  Skipping {}", obj.getRelativePath());
                    return;
                }
            }
        }

        // at this point we know we are going to write the object
        // Put [current object version]
        if (obj instanceof S3ObjectVersion && ((S3ObjectVersion) obj).isDeleteMarker()) {

            // object has version history, but is currently deleted
            log.debug("[{}]: deleting object in target to replicate delete marker in source.",
                    obj.getRelativePath());
            s3.deleteObject(bucketName, targetKey);
        } else {
            putObject(obj, targetKey);

            // if object has new metadata after the stream (i.e. encryption checksum), we must update S3 again
            if (obj.requiresPostStreamMetadataUpdate()) {
                log.debug("[{}]: updating metadata after sync as required", obj.getRelativePath());
                CopyObjectRequest cReq = new CopyObjectRequest(bucketName, targetKey, bucketName, targetKey);
                cReq.setNewObjectMetadata(AwsS3Util.s3MetaFromSyncMeta(obj.getMetadata()));
                s3.copyObject(cReq);
            }
        }
    } catch (Exception e) {
        throw new RuntimeException("Failed to store object: " + e, e);
    }
}

From source file:au.org.emii.portal.composer.MapComposer.java

public void loadUserSession(String sessionid) {
    Scanner scanner = null;/*from   w  w  w. j  a v  a 2  s. c  o  m*/
    try {

        String sfld = getSettingsSupplementary().getProperty(StringConstants.ANALYSIS_OUTPUT_DIR) + "session/"
                + sessionid;

        File sessfolder = new File(sfld);
        if (!sessfolder.exists()) {
            showMessage("Session information does not exist. Please provide a valid session id");
            return;
        }

        scanner = new Scanner(new File(sfld + "/details.txt"));

        // first grab the zoom level and bounding box
        String[] mapdetails = scanner.nextLine().split(",");

        BoundingBox bb = new BoundingBox();
        bb.setMinLongitude(Float.parseFloat(mapdetails[1]));
        bb.setMinLatitude(Float.parseFloat(mapdetails[2]));
        bb.setMaxLongitude(Float.parseFloat(mapdetails[3]));
        bb.setMaxLatitude(Float.parseFloat(mapdetails[4]));
        openLayersJavascript.setAdditionalScript(openLayersJavascript.zoomToBoundingBox(bb, true));

        String[] scatterplotNames = null;
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            if (line.startsWith("scatterplotNames")) {
                scatterplotNames = line.substring(17).split("___");
            }
        }
        ArrayUtils.reverse(scatterplotNames);

        // ignore fields not found
        XStream xstream = new XStream(new DomDriver()) {

            protected MapperWrapper wrapMapper(MapperWrapper next) {
                return new MapperWrapper(next) {
                    public boolean shouldSerializeMember(Class definedIn, String fieldName) {
                        if (definedIn == Object.class || !super.shouldSerializeMember(definedIn, fieldName))
                            System.out.println("faled to read: " + definedIn + ", " + fieldName);

                        return definedIn != Object.class ? super.shouldSerializeMember(definedIn, fieldName)
                                : false;
                    }
                };
            }

            @Override
            public Object unmarshal(HierarchicalStreamReader reader) {
                Object o = super.unmarshal(reader);
                if (o instanceof BiocacheQuery)
                    ((BiocacheQuery) o).getFullQ(false);
                return o;
            }

            @Override
            public Object unmarshal(HierarchicalStreamReader reader, Object root) {
                Object o = super.unmarshal(reader, root);
                if (o instanceof BiocacheQuery)
                    ((BiocacheQuery) o).getFullQ(false);
                return o;
            }

            @Override
            public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder dataHolder) {
                Object o = super.unmarshal(reader, root, dataHolder);
                if (o instanceof BiocacheQuery)
                    ((BiocacheQuery) o).getFullQ(false);
                return o;
            }
        };

        PersistenceStrategy strategy = new FilePersistenceStrategy(new File(sfld), xstream);

        List list = new XmlArrayList(strategy);

        ListIterator it = list.listIterator(list.size());
        int scatterplotIndex = 0;
        while (it.hasPrevious()) {
            Object o = it.previous();
            MapLayer ml = null;
            if (o instanceof MapLayer) {
                ml = (MapLayer) o;
                LOGGER.debug("Loading " + ml.getName() + " -> " + ml.isDisplayed());
                addUserDefinedLayerToMenu(ml, false);
            } else if (o instanceof ScatterplotDataDTO) {
                ScatterplotDataDTO spdata = (ScatterplotDataDTO) o;
                loadScatterplot(spdata, "My Scatterplot " + scatterplotIndex++);

            }

            if (ml != null) {
                addUserDefinedLayerToMenu(ml, true);
            }
        }

    } catch (Exception e) {
        try {

            File f = new File("/data/sessions/" + sessionid + ".txt");

            PrintWriter pw = new PrintWriter(f);

            e.printStackTrace(pw);

            pw.close();

        } catch (Exception ex) {

        }
        LOGGER.error("Unable to load session data", e);
        showMessage("Unable to load session data");

    } finally {
        if (scanner != null) {
            scanner.close();
        }
        try {

            File f = new File("/data/sessions/ok/" + sessionid + ".txt");

            FileUtils.writeStringToFile(f, "ok");

        } catch (Exception ex) {

        }
    }
}

From source file:org.trnltk.experiment.morphology.ambiguity.DataDiffUtil.java

/**
 * Reduce the number of edits by eliminating semantically trivial equalities.
 *
 * @param diffs LinkedList of Diff objects.
 */// w  w w  . ja  va  2 s .  c o m
public void diff_cleanupSemantic(LinkedList<Diff<T>> diffs) {
    if (diffs.isEmpty()) {
        return;
    }
    boolean changes = false;
    Stack<Diff<T>> equalities = new Stack<Diff<T>>(); // Stack of qualities.
    List<T> lastequality = null; // Always equal to equalities.lastElement().text
    ListIterator<Diff<T>> pointer = diffs.listIterator();
    // Number of characters that changed prior to the equality.
    int length_insertions1 = 0;
    int length_deletions1 = 0;
    // Number of characters that changed after the equality.
    int length_insertions2 = 0;
    int length_deletions2 = 0;
    Diff<T> thisDiff = pointer.next();
    while (thisDiff != null) {
        if (thisDiff.operation == Operation.EQUAL) {
            // Equality found.
            equalities.push(thisDiff);
            length_insertions1 = length_insertions2;
            length_deletions1 = length_deletions2;
            length_insertions2 = 0;
            length_deletions2 = 0;
            lastequality = thisDiff.text;
        } else {
            // An insertion or deletion.
            if (thisDiff.operation == Operation.INSERT) {
                length_insertions2 += thisDiff.text.size();
            } else {
                length_deletions2 += thisDiff.text.size();
            }
            // Eliminate an equality that is smaller or equal to the edits on both
            // sides of it.
            if (lastequality != null && (lastequality.size() <= Math.max(length_insertions1, length_deletions1))
                    && (lastequality.size() <= Math.max(length_insertions2, length_deletions2))) {
                //System.out.println("Splitting: '" + lastequality + "'");
                // Walk back to offending equality.
                while (thisDiff != equalities.lastElement()) {
                    thisDiff = pointer.previous();
                }
                pointer.next();

                // Replace equality with a delete.
                pointer.set(new Diff(Operation.DELETE, lastequality));
                // Insert a corresponding an insert.
                pointer.add(new Diff(Operation.INSERT, lastequality));

                equalities.pop(); // Throw away the equality we just deleted.
                if (!equalities.empty()) {
                    // Throw away the previous equality (it needs to be reevaluated).
                    equalities.pop();
                }
                if (equalities.empty()) {
                    // There are no previous equalities, walk back to the start.
                    while (pointer.hasPrevious()) {
                        pointer.previous();
                    }
                } else {
                    // There is a safe equality we can fall back to.
                    thisDiff = equalities.lastElement();
                    while (thisDiff != pointer.previous()) {
                        // Intentionally empty loop.
                    }
                }

                length_insertions1 = 0; // Reset the counters.
                length_insertions2 = 0;
                length_deletions1 = 0;
                length_deletions2 = 0;
                lastequality = null;
                changes = true;
            }
        }
        thisDiff = pointer.hasNext() ? pointer.next() : null;
    }

    // Normalize the diff.
    if (changes) {
        diff_cleanupMerge(diffs);
    }
    diff_cleanupSemanticLossless(diffs);

    // Find any overlaps between deletions and insertions.
    // e.g: <del>abcxxx</del><ins>xxxdef</ins>
    //   -> <del>abc</del>xxx<ins>def</ins>
    // e.g: <del>xxxabc</del><ins>defxxx</ins>
    //   -> <ins>def</ins>xxx<del>abc</del>
    // Only extract an overlap if it is as big as the edit ahead or behind it.
    pointer = diffs.listIterator();
    Diff<T> prevDiff = null;
    thisDiff = null;
    if (pointer.hasNext()) {
        prevDiff = pointer.next();
        if (pointer.hasNext()) {
            thisDiff = pointer.next();
        }
    }
    while (thisDiff != null) {
        if (prevDiff.operation == Operation.DELETE && thisDiff.operation == Operation.INSERT) {
            List<T> deletion = prevDiff.text;
            List<T> insertion = thisDiff.text;
            int overlap_length1 = this.diff_commonOverlap(deletion, insertion);
            int overlap_length2 = this.diff_commonOverlap(insertion, deletion);
            if (overlap_length1 >= overlap_length2) {
                if (overlap_length1 >= deletion.size() / 2.0 || overlap_length1 >= insertion.size() / 2.0) {
                    // Overlap found. Insert an equality and trim the surrounding edits.
                    pointer.previous();
                    pointer.add(new Diff<T>(Operation.EQUAL, insertion.subList(0, overlap_length1)));
                    prevDiff.text = deletion.subList(0, deletion.size() - overlap_length1);
                    thisDiff.text = insertion.subList(overlap_length1, insertion.size());
                    // pointer.add inserts the element before the cursor, so there is
                    // no need to step past the new element.
                }
            } else {
                if (overlap_length2 >= deletion.size() / 2.0 || overlap_length2 >= insertion.size() / 2.0) {
                    // Reverse overlap found.
                    // Insert an equality and swap and trim the surrounding edits.
                    pointer.previous();
                    pointer.add(new Diff<T>(Operation.EQUAL, deletion.subList(0, overlap_length2)));
                    prevDiff.operation = Operation.INSERT;
                    prevDiff.text = insertion.subList(0, insertion.size() - overlap_length2);
                    thisDiff.operation = Operation.DELETE;
                    thisDiff.text = deletion.subList(overlap_length2, deletion.size());
                    // pointer.add inserts the element before the cursor, so there is
                    // no need to step past the new element.
                }
            }
            thisDiff = pointer.hasNext() ? pointer.next() : null;
        }
        prevDiff = thisDiff;
        thisDiff = pointer.hasNext() ? pointer.next() : null;
    }
}

From source file:com.emc.ecs.sync.target.EcsS3Target.java

@Override
public void filter(SyncObject obj) {
    try {//from  w w w  .  j  a  v  a2s.  co m
        // skip the root of the bucket since it obviously exists
        if ("".equals(rootKey + obj.getRelativePath())) {
            log.debug("Target is bucket root; skipping");
            return;
        }

        // some sync objects lazy-load their metadata (i.e. AtmosSyncObject)
        // since this may be a timed operation, ensure it loads outside of other timed operations
        if (!(obj instanceof EcsS3ObjectVersion) || !((EcsS3ObjectVersion) obj).isDeleteMarker())
            obj.getMetadata();

        // Compute target key
        final String targetKey = getTargetKey(obj);
        obj.setTargetIdentifier(AwsS3Util.fullPath(bucketName, targetKey));

        if (includeVersions) {
            ListIterator<EcsS3ObjectVersion> sourceVersions = s3Source.versionIterator((EcsS3SyncObject) obj);
            ListIterator<EcsS3ObjectVersion> targetVersions = versionIterator(obj);

            boolean newVersions = false, replaceVersions = false;
            if (force) {
                replaceVersions = true;
            } else {

                // special workaround for bug where objects are listed, but they have no versions
                if (sourceVersions.hasNext()) {

                    // check count and etag/delete-marker to compare version chain
                    while (sourceVersions.hasNext()) {
                        EcsS3ObjectVersion sourceVersion = sourceVersions.next();

                        if (targetVersions.hasNext()) {
                            EcsS3ObjectVersion targetVersion = targetVersions.next();

                            if (sourceVersion.isDeleteMarker()) {

                                if (!targetVersion.isDeleteMarker())
                                    replaceVersions = true;
                            } else {

                                if (targetVersion.isDeleteMarker())
                                    replaceVersions = true;

                                else if (!sourceVersion.getETag().equals(targetVersion.getETag()))
                                    replaceVersions = true; // different checksum
                            }

                        } else if (!replaceVersions) { // source has new versions, but existing target versions are ok
                            newVersions = true;
                            sourceVersions.previous(); // back up one
                            putIntermediateVersions(sourceVersions, targetKey); // add any new intermediary versions (current is added below)
                        }
                    }

                    if (targetVersions.hasNext())
                        replaceVersions = true; // target has more versions

                    if (!newVersions && !replaceVersions) {
                        log.info("Source and target versions are the same.  Skipping {}",
                                obj.getRelativePath());
                        return;
                    }
                }
            }

            // something's off; must delete all versions of the object
            if (replaceVersions) {
                log.info(
                        "[{}]: version history differs between source and target; re-placing target version history with that from source.",
                        obj.getRelativePath());

                // collect versions in target
                final List<ObjectKey> deleteVersions = new ArrayList<>();
                while (targetVersions.hasNext())
                    targetVersions.next(); // move cursor to end
                while (targetVersions.hasPrevious()) { // go in reverse order
                    EcsS3ObjectVersion version = targetVersions.previous();
                    deleteVersions.add(new ObjectKey(targetKey, version.getVersionId()));
                }

                // batch delete all versions in target
                log.debug("[{}]: deleting all versions in target", obj.getRelativePath());
                time(new Function<Void>() {
                    @Override
                    public Void call() {
                        s3.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(deleteVersions));
                        return null;
                    }
                }, OPERATION_DELETE_VERSIONS);

                // replay version history in target
                while (sourceVersions.hasPrevious())
                    sourceVersions.previous(); // move cursor to beginning
                putIntermediateVersions(sourceVersions, targetKey);
            }

        } else { // normal sync (no versions)
            Date sourceLastModified = obj.getMetadata().getModificationTime();
            long sourceSize = obj.getMetadata().getContentLength();

            // Get target metadata.
            S3ObjectMetadata destMeta = null;
            try {
                destMeta = time(new Function<S3ObjectMetadata>() {
                    @Override
                    public S3ObjectMetadata call() {
                        return s3.getObjectMetadata(bucketName, targetKey);
                    }
                }, OPERATION_GET_METADATA);
            } catch (S3Exception e) {
                if (e.getHttpCode() != 404) {
                    throw new RuntimeException("Failed to check target key '" + targetKey + "' : " + e, e);
                }
            }

            if (!force && obj.getFailureCount() == 0 && destMeta != null) {

                // Check overwrite
                Date destLastModified = destMeta.getLastModified();
                long destSize = destMeta.getContentLength();

                if (destLastModified.equals(sourceLastModified) && sourceSize == destSize) {
                    log.info("Source and target the same.  Skipping {}", obj.getRelativePath());
                    return;
                }
                if (destLastModified.after(sourceLastModified)) {
                    log.info("Target newer than source.  Skipping {}", obj.getRelativePath());
                    return;
                }
            }
        }

        // at this point we know we are going to write the object
        // Put [current object version]
        if (obj instanceof S3ObjectVersion && ((S3ObjectVersion) obj).isDeleteMarker()) {

            // object has version history, but is currently deleted
            log.debug("[{}]: deleting object in target to replicate delete marker in source.",
                    obj.getRelativePath());
            time(new Function<Void>() {
                @Override
                public Void call() {
                    s3.deleteObject(bucketName, targetKey);
                    return null;
                }
            }, OPERATION_DELETE_OBJECT);
        } else {
            putObject(obj, targetKey);

            // if object has new metadata after the stream (i.e. encryption checksum), we must update S3 again
            if (obj.requiresPostStreamMetadataUpdate()) {
                log.debug("[{}]: updating metadata after sync as required", obj.getRelativePath());
                final CopyObjectRequest cReq = new CopyObjectRequest(bucketName, targetKey, bucketName,
                        targetKey);
                cReq.setObjectMetadata(EcsS3Util.s3MetaFromSyncMeta(obj.getMetadata()));
                time(new Function<Void>() {
                    @Override
                    public Void call() {
                        s3.copyObject(cReq);
                        return null;
                    }
                }, OPERATION_UPDATE_METADATA);
            }
        }
    } catch (Exception e) {
        throw new RuntimeException("Failed to store object: " + e, e);
    }
}

From source file:org.fenixedu.academic.domain.student.Registration.java

final public ICurriculum getCurriculum(final DateTime when, final ExecutionYear executionYear,
        final CycleType cycleType) {
    if (getStudentCurricularPlansSet().isEmpty()) {
        return Curriculum.createEmpty(executionYear);
    }//w  w  w.j a  v  a  2 s . c o m

    if (getDegreeType().isBolonhaType()) {
        final StudentCurricularPlan studentCurricularPlan = getLastStudentCurricularPlan();
        if (studentCurricularPlan == null) {
            return Curriculum.createEmpty(executionYear);
        }

        if (cycleType == null) {
            return studentCurricularPlan.getCurriculum(when, executionYear);
        }

        final CycleCurriculumGroup cycleCurriculumGroup = studentCurricularPlan.getCycle(cycleType);
        if (cycleCurriculumGroup == null) {
            return Curriculum.createEmpty(executionYear);
        }

        return cycleCurriculumGroup.getCurriculum(when, executionYear);
    } else {
        final List<StudentCurricularPlan> sortedSCPs = getSortedStudentCurricularPlans();
        final ListIterator<StudentCurricularPlan> sortedSCPsIterator = sortedSCPs
                .listIterator(sortedSCPs.size());
        final StudentCurricularPlan lastStudentCurricularPlan = sortedSCPsIterator.previous();

        final ICurriculum curriculum;
        curriculum = lastStudentCurricularPlan.getCurriculum(when, executionYear);

        for (; sortedSCPsIterator.hasPrevious();) {
            final StudentCurricularPlan studentCurricularPlan = sortedSCPsIterator.previous();
            if (executionYear == null
                    || studentCurricularPlan.getStartExecutionYear().isBeforeOrEquals(executionYear)) {
                ((Curriculum) curriculum).add(studentCurricularPlan.getCurriculum(when, executionYear));
            }
        }

        return curriculum;

    }
}

From source file:com.ludoscity.findmybikes.activities.NearbyActivity.java

@Override
public void onFavoriteSheetEditDone() {

    ArrayList<FavoriteItemBase> newlyOrderedFavList = new ArrayList<>();
    newlyOrderedFavList.addAll(mFavoriteRecyclerViewAdapter.getCurrentFavoriteList());

    DBHelper.dropFavoriteAll(this);
    mFavoriteRecyclerViewAdapter.clearFavoriteList();

    ListIterator<FavoriteItemBase> li = newlyOrderedFavList.listIterator(newlyOrderedFavList.size());

    while (li.hasPrevious()) {
        addFavorite(li.previous(), true, false);
    }/*from w  w w  . j a  va2 s  .  c o m*/
}

From source file:net.sourceforge.fenixedu.domain.student.Registration.java

final public ICurriculum getCurriculum(final DateTime when, final ExecutionYear executionYear,
        final CycleType cycleType) {
    if (getStudentCurricularPlansSet().isEmpty()) {
        return Curriculum.createEmpty(executionYear);
    }//from   ww  w  .j  av a  2  s . c  o  m

    if (getDegreeType().isBolonhaType()) {
        final StudentCurricularPlan studentCurricularPlan = getLastStudentCurricularPlan();
        if (studentCurricularPlan == null) {
            return Curriculum.createEmpty(executionYear);
        }

        if (cycleType == null) {
            return studentCurricularPlan.getCurriculum(when, executionYear);
        }

        final CycleCurriculumGroup cycleCurriculumGroup = studentCurricularPlan.getCycle(cycleType);
        if (cycleCurriculumGroup == null) {
            return Curriculum.createEmpty(executionYear);
        }

        return cycleCurriculumGroup.getCurriculum(when, executionYear);
    } else {
        final List<StudentCurricularPlan> sortedSCPs = getSortedStudentCurricularPlans();
        final ListIterator<StudentCurricularPlan> sortedSCPsIterator = sortedSCPs
                .listIterator(sortedSCPs.size());
        final StudentCurricularPlan lastStudentCurricularPlan = sortedSCPsIterator.previous();

        final ICurriculum curriculum;
        if (lastStudentCurricularPlan.isBoxStructure()) {
            curriculum = lastStudentCurricularPlan.getCurriculum(when, executionYear);

            for (; sortedSCPsIterator.hasPrevious();) {
                final StudentCurricularPlan studentCurricularPlan = sortedSCPsIterator.previous();
                if (executionYear == null
                        || studentCurricularPlan.getStartExecutionYear().isBeforeOrEquals(executionYear)) {
                    ((Curriculum) curriculum).add(studentCurricularPlan.getCurriculum(when, executionYear));
                }
            }

            return curriculum;

        } else {
            curriculum = new StudentCurriculum(this, executionYear);
        }

        return curriculum;
    }
}