Example usage for java.util Optional get

List of usage examples for java.util Optional get

Introduction

In this page you can find the example usage for java.util Optional get.

Prototype

public T get() 

Source Link

Document

If a value is present, returns the value, otherwise throws NoSuchElementException .

Usage

From source file:net.sf.jabref.util.Util.java

/**
 * Automatically add links for this set of entries, based on the globally stored list of external file types. The
 * entries are modified, and corresponding UndoEdit elements added to the NamedCompound given as argument.
 * Furthermore, all entries which are modified are added to the Set of entries given as an argument.
 * <p>/*from  www  .  jav a 2s  .c o m*/
 * The entries' bibtex keys must have been set - entries lacking key are ignored. The operation is done in a new
 * thread, which is returned for the caller to wait for if needed.
 *
 * @param entries          A collection of BibEntry objects to find links for.
 * @param ce               A NamedCompound to add UndoEdit elements to.
 * @param changedEntries   MODIFIED, optional. A Set of BibEntry objects to which all modified entries is added.
 *                         This is used for status output and debugging
 * @param singleTableModel UGLY HACK. The table model to insert links into. Already existing links are not
 *                         duplicated or removed. This parameter has to be null if entries.count() != 1. The hack has been
 *                         introduced as a bibtexentry does not (yet) support the function getListTableModel() and the
 *                         FileListEntryEditor editor holds an instance of that table model and does not reconstruct it after the
 *                         search has succeeded.
 * @param metaData         The MetaData providing the relevant file directory, if any.
 * @param callback         An ActionListener that is notified (on the event dispatch thread) when the search is finished.
 *                         The ActionEvent has id=0 if no new links were added, and id=1 if one or more links were added. This
 *                         parameter can be null, which means that no callback will be notified.
 * @param diag             An instantiated modal JDialog which will be used to display the progress of the autosetting. This
 *                         parameter can be null, which means that no progress update will be shown.
 * @return the thread performing the autosetting
 */
public static Runnable autoSetLinks(final Collection<BibEntry> entries, final NamedCompound ce,
        final Set<BibEntry> changedEntries, final FileListTableModel singleTableModel, final MetaData metaData,
        final ActionListener callback, final JDialog diag) {
    final Collection<ExternalFileType> types = ExternalFileTypes.getInstance().getExternalFileTypeSelection();
    if (diag != null) {
        final JProgressBar prog = new JProgressBar(JProgressBar.HORIZONTAL, 0, types.size() - 1);
        final JLabel label = new JLabel(Localization.lang("Searching for files"));
        prog.setIndeterminate(true);
        prog.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        diag.setTitle(Localization.lang("Autosetting links"));
        diag.getContentPane().add(prog, BorderLayout.CENTER);
        diag.getContentPane().add(label, BorderLayout.SOUTH);

        diag.pack();
        diag.setLocationRelativeTo(diag.getParent());
    }

    Runnable r = new Runnable() {

        @Override
        public void run() {
            // determine directories to search in
            List<File> dirs = new ArrayList<>();
            List<String> dirsS = metaData.getFileDirectory(Globals.FILE_FIELD);
            for (String dirs1 : dirsS) {
                dirs.add(new File(dirs1));
            }

            // determine extensions
            Collection<String> extensions = new ArrayList<>();
            for (final ExternalFileType type : types) {
                extensions.add(type.getExtension());
            }

            // Run the search operation:
            Map<BibEntry, List<File>> result;
            if (Globals.prefs.getBoolean(JabRefPreferences.AUTOLINK_USE_REG_EXP_SEARCH_KEY)) {
                String regExp = Globals.prefs.get(JabRefPreferences.REG_EXP_SEARCH_EXPRESSION_KEY);
                result = RegExpFileSearch.findFilesForSet(entries, extensions, dirs, regExp);
            } else {
                result = FileUtil.findAssociatedFiles(entries, extensions, dirs);
            }

            boolean foundAny = false;
            // Iterate over the entries:
            for (Entry<BibEntry, List<File>> entryFilePair : result.entrySet()) {
                FileListTableModel tableModel;
                String oldVal = entryFilePair.getKey().getField(Globals.FILE_FIELD);
                if (singleTableModel == null) {
                    tableModel = new FileListTableModel();
                    if (oldVal != null) {
                        tableModel.setContent(oldVal);
                    }
                } else {
                    assert entries.size() == 1;
                    tableModel = singleTableModel;
                }
                List<File> files = entryFilePair.getValue();
                for (File f : files) {
                    f = FileUtil.shortenFileName(f, dirsS);
                    boolean alreadyHas = false;
                    //System.out.println("File: "+f.getPath());
                    for (int j = 0; j < tableModel.getRowCount(); j++) {
                        FileListEntry existingEntry = tableModel.getEntry(j);
                        //System.out.println("Comp: "+existingEntry.getLink());
                        if (new File(existingEntry.link).equals(f)) {
                            alreadyHas = true;
                            break;
                        }
                    }
                    if (!alreadyHas) {
                        foundAny = true;
                        ExternalFileType type;
                        Optional<String> extension = FileUtil.getFileExtension(f);
                        if (extension.isPresent()) {
                            type = ExternalFileTypes.getInstance().getExternalFileTypeByExt(extension.get());
                        } else {
                            type = new UnknownExternalFileType("");
                        }
                        FileListEntry flEntry = new FileListEntry(f.getName(), f.getPath(), type);
                        tableModel.addEntry(tableModel.getRowCount(), flEntry);

                        String newVal = tableModel.getStringRepresentation();
                        if (newVal.isEmpty()) {
                            newVal = null;
                        }
                        if (ce != null) {
                            // store undo information
                            UndoableFieldChange change = new UndoableFieldChange(entryFilePair.getKey(),
                                    Globals.FILE_FIELD, oldVal, newVal);
                            ce.addEdit(change);
                        }
                        // hack: if table model is given, do NOT modify entry
                        if (singleTableModel == null) {
                            entryFilePair.getKey().setField(Globals.FILE_FIELD, newVal);
                        }
                        if (changedEntries != null) {
                            changedEntries.add(entryFilePair.getKey());
                        }
                    }
                }
            }

            // handle callbacks and dialog
            // FIXME: The ID signals if action was successful :/
            final int id = foundAny ? 1 : 0;
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    if (diag != null) {
                        diag.dispose();
                    }
                    if (callback != null) {
                        callback.actionPerformed(new ActionEvent(this, id, ""));
                    }
                }
            });
        }
    };
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            // show dialog which will be hidden when the task is done
            if (diag != null) {
                diag.setVisible(true);
            }
        }
    });
    return r;
}

From source file:com.helion3.prism.api.query.QueryBuilder.java

/**
 * Builds a {@link Query} by parsing an array of arguments.
 *
 * @param parameters String[] Parameter:value list
 * @return {@link Query} Database query object
 *//*  w w w . j av  a  2s  .c om*/
public static CompletableFuture<Query> fromArguments(QuerySession session, @Nullable String[] arguments)
        throws ParameterException {
    checkNotNull(session);

    Query query = new Query();
    CompletableFuture<Query> future = new CompletableFuture<Query>();

    // Track all parameter pairs
    Map<String, String> definedParameters = new HashMap<String, String>();

    if (arguments.length > 0) {
        List<ListenableFuture<?>> futures = new ArrayList<ListenableFuture<?>>();
        for (String arg : arguments) {
            Optional<ListenableFuture<?>> listenable;

            if (flagPattern.matcher(arg).matches()) {
                listenable = parseFlagFromArgument(session, query, arg);
            } else {
                // Get alias/value pair
                Pair<String, String> pair = getParameterKeyValue(arg);

                // Parse for handler
                listenable = parseParameterFromArgument(session, query, pair);

                // Add to list of defined
                definedParameters.put(pair.getKey(), pair.getValue());
            }

            if (listenable.isPresent()) {
                futures.add(listenable.get());
            }
        }

        if (!futures.isEmpty()) {
            ListenableFuture<List<Object>> combinedFuture = Futures.allAsList(futures);
            combinedFuture.addListener(new Runnable() {
                @Override
                public void run() {
                    future.complete(query);
                }
            }, MoreExecutors.sameThreadExecutor());
        } else {
            future.complete(query);
        }
    } else {
        future.complete(query);
    }

    if (Prism.getConfig().getNode("defaults", "enabled").getBoolean()) {
        // Require any parameter defaults
        String defaultsUsed = "";
        for (ParameterHandler handler : Prism.getParameterHandlers()) {
            boolean aliasFound = false;

            for (String alias : handler.getAliases()) {
                if (definedParameters.containsKey(alias)) {
                    aliasFound = true;
                    break;
                }
            }

            if (!aliasFound) {
                Optional<Pair<String, String>> pair = handler.processDefault(session, query);
                if (pair.isPresent()) {
                    defaultsUsed += pair.get().getKey() + ":" + pair.get().getValue() + " ";
                }
            }
        }

        // @todo should move this
        if (!defaultsUsed.isEmpty()) {
            session.getCommandSource().get().sendMessage(
                    Format.subduedHeading(Text.of(String.format("Defaults used: %s", defaultsUsed))));
        }
    }

    return future;
}

From source file:io.github.retz.web.WebConsole.java

public static String schedule(Request req, Response res) throws IOException, InterruptedException {
    ScheduleRequest scheduleRequest = MAPPER.readValue(req.bodyAsBytes(), ScheduleRequest.class);
    res.type("application/json");
    Optional<Application> maybeApp = Applications.get(scheduleRequest.job().appid()); // TODO check owner right here
    if (!maybeApp.isPresent()) {
        // TODO: this warn log cannot be written in real stable release
        LOG.warn("No such application loaded: {}", scheduleRequest.job().appid());
        ErrorResponse response = new ErrorResponse("No such application: " + scheduleRequest.job().appid());
        res.status(404);//from   w  w  w . j  ava  2s  .c o m
        return MAPPER.writeValueAsString(response);

    } else if (maybeApp.get().enabled()) {

        validateOwner(req, maybeApp.get());

        Job job = scheduleRequest.job();
        if (scheduler.isPresent()) {
            if (!scheduler.get().validateJob(job)) {
                String msg = "Job " + job.toString() + " does not fit system limit "
                        + scheduler.get().maxJobSize();
                // TODO: this warn log cannot be written in real stable release
                LOG.warn(msg);
                halt(400, msg);
            }
        }

        job.schedule(JobQueue.issueJobId(), TimestampHelper.now());

        JobQueue.push(job);
        if (scheduler.isPresent() && driver.isPresent()) {
            LOG.info("Trying invocation from offer stock: {}", job);
            scheduler.get().maybeInvokeNow(driver.get(), job);

        }

        ScheduleResponse scheduleResponse = new ScheduleResponse(job);
        scheduleResponse.ok();
        LOG.info("Job '{}' at {} has been scheduled at {}.", job.cmd(), job.appid(), job.scheduled());

        res.status(201);
        return MAPPER.writeValueAsString(scheduleResponse);

    } else {
        // Application is currently disabled
        res.status(401);
        ErrorResponse response = new ErrorResponse("Application " + maybeApp.get().getAppid() + " is disabled");
        return MAPPER.writeValueAsString(response);
    }
}

From source file:io.pravega.controller.store.stream.tables.TableHelper.java

private static Optional<HistoryRecord> findSegmentSealedEvent(final int lower, final int upper,
        final int segmentNumber, final byte[] indexTable, final byte[] historyTable) {

    if (lower > upper || historyTable.length == 0) {
        return Optional.empty();
    }/*w ww  . j  a v a  2  s. com*/

    final int offset = ((lower + upper) / 2) * IndexRecord.INDEX_RECORD_SIZE;

    final Optional<IndexRecord> indexRecord = IndexRecord.readRecord(indexTable, offset);

    final Optional<IndexRecord> previousIndex = indexRecord.isPresent()
            ? IndexRecord.fetchPrevious(indexTable, offset)
            : Optional.empty();

    final int historyTableOffset = indexRecord.isPresent() ? indexRecord.get().getHistoryOffset() : 0;
    final Optional<HistoryRecord> record = HistoryRecord.readRecord(historyTable, historyTableOffset, false);

    // if segment is not present in history record, check if it is present in previous
    // if yes, we have found the segment sealed event
    // else repeat binary searchIndex
    if (!record.get().getSegments().contains(segmentNumber)) {
        assert previousIndex.isPresent();

        final Optional<HistoryRecord> previousRecord = HistoryRecord.readRecord(historyTable,
                previousIndex.get().getHistoryOffset(), false);
        if (previousRecord.get().getSegments().contains(segmentNumber)) {
            return record; // search complete
        } else { // binary search lower
            return findSegmentSealedEvent(lower, (lower + upper) / 2 - 1, segmentNumber, indexTable,
                    historyTable);
        }
    } else { // binary search upper
        // not sealed in the current location: look in second half
        return findSegmentSealedEvent((lower + upper) / 2 + 1, upper, segmentNumber, indexTable, historyTable);
    }
}

From source file:com.facebook.presto.accumulo.AccumuloClient.java

/**
 * Searches through the given locality groups to find if this column has a locality group.
 *
 * @param columnName Column name to get the locality group of
 * @param groups Optional locality group configuration
 * @return Optional string containing the name of the locality group, if present
 *//*from w  w w .  java  2  s .  co m*/
private static Optional<String> getColumnLocalityGroup(String columnName,
        Optional<Map<String, Set<String>>> groups) {
    if (groups.isPresent()) {
        for (Map.Entry<String, Set<String>> group : groups.get().entrySet()) {
            if (group.getValue().contains(columnName.toLowerCase(Locale.ENGLISH))) {
                return Optional.of(group.getKey());
            }
        }
    }

    return Optional.empty();
}

From source file:de.tu_dortmund.ub.data.dswarm.TaskProcessingUnit.java

public static String startTPU(final String confFile, final Properties config) throws Exception {

    final String serviceName = config.getProperty(TPUStatics.SERVICE_NAME_IDENTIFIER);

    LOG.info(String.format("[%s] Starting 'Task Processing Unit' ...", serviceName));
    LOG.info(String.format("[%s] conf-file = %s", serviceName, confFile));

    final String resourceWatchFolder = config.getProperty(TPUStatics.RESOURCE_WATCHFOLDER_IDENTIFIER);
    String[] watchFolderFiles = new File(resourceWatchFolder).list();

    if (watchFolderFiles == null) {

        final String message = String.format(
                "could not determine files from watchfolder '%s'; watch folder file list does not exist",
                resourceWatchFolder);/*www.  j a va2 s  .  co  m*/

        TaskProcessingUnit.LOG.error(message);

        throw new TPUException(message);
    }

    if (watchFolderFiles.length == 0) {

        final String message = String.format(
                "could not determine files from watchfolder; there are no files in folder '%s'",
                resourceWatchFolder);

        TaskProcessingUnit.LOG.error(message);

        throw new TPUException(message);
    }

    Arrays.sort(watchFolderFiles);

    final String filesMessage = String.format("[%s] '%s' files in resource watch folder '%s'", serviceName,
            watchFolderFiles.length, resourceWatchFolder);

    LOG.info(filesMessage);
    LOG.info("\tfile names: '" + Arrays.toString(watchFolderFiles) + "'");

    // Init time counter
    final long global = System.currentTimeMillis();

    final Integer engineThreads = Integer.parseInt(config.getProperty(TPUStatics.ENGINE_THREADS_IDENTIFIER));

    final Optional<Boolean> optionalDoInit = TPUUtil.getBooleanConfigValue(TPUStatics.DO_INIT_IDENTIFIER,
            config);
    final Optional<Boolean> optionalDoTransformations = TPUUtil
            .getBooleanConfigValue(TPUStatics.DO_TRANSFORMATIONS_IDENTIFIER, config);
    final Optional<Boolean> optionalAllowMultipleDataModels = TPUUtil
            .getBooleanConfigValue(TPUStatics.ALLOW_MULTIPLE_DATA_MODELS_IDENTIFIER, config);
    final Optional<Boolean> optionalDoIngestOnTheFly = TPUUtil
            .getBooleanConfigValue(TPUStatics.DO_INGEST_ON_THE_FLY_IDENTIFIER, config);
    final Optional<Boolean> optionalDoExportOnTheFly = TPUUtil
            .getBooleanConfigValue(TPUStatics.DO_EXPORT_ON_THE_FLY_IDENTIFIER, config);
    final Optional<String> optionalOutputDataModelID = TPUUtil
            .getStringConfigValue(TPUStatics.PROTOTYPE_OUTPUT_DATA_MODEL_ID_IDENTIFIER, config);

    final Optional<String> optionalExportMimeType;

    if (optionalDoExportOnTheFly.isPresent() && optionalDoExportOnTheFly.get()) {

        optionalExportMimeType = TPUUtil.getStringConfigValue(TPUStatics.EXPORT_MIME_TYPE, config);
    } else {

        optionalExportMimeType = Optional.empty();
    }

    final Optional<String> optionalExportFileExtension;

    if (optionalExportMimeType.isPresent()) {

        String exportFileExtension;
        try {

            final MediaType mediaType = MediaType.getMediaTypeByName(optionalExportMimeType.get());
            exportFileExtension = mediaType.getFileExtension();
        } catch (final DSWARMException e) {

            // xml as default file extension
            exportFileExtension = XML_FILE_ENDING;
        }

        optionalExportFileExtension = Optional.ofNullable(exportFileExtension);
    } else {

        optionalExportFileExtension = Optional.empty();
    }

    final String result;

    if (goMultiThreaded(optionalDoInit, optionalDoTransformations, optionalAllowMultipleDataModels,
            optionalDoIngestOnTheFly, optionalDoExportOnTheFly)) {

        result = executeTPUTask(watchFolderFiles, resourceWatchFolder, optionalOutputDataModelID,
                optionalExportMimeType, optionalExportFileExtension, engineThreads, serviceName, config);
    } else {

        executeTPUPartsOnDemand(optionalDoInit, optionalAllowMultipleDataModels, watchFolderFiles,
                resourceWatchFolder, optionalOutputDataModelID, serviceName, engineThreads,
                optionalDoTransformations, optionalDoIngestOnTheFly, optionalDoExportOnTheFly,
                optionalExportMimeType, optionalExportFileExtension, config);

        result = "[no result available]";
    }

    final String tasksExecutedMessage = String.format("[%s] d:swarm tasks executed. (Processing time: %d s)",
            serviceName, ((System.currentTimeMillis() - global) / 1000));

    LOG.info(tasksExecutedMessage);

    return result;
}

From source file:com.skelril.skree.content.registry.item.zone.ZoneItemUtil.java

public static void rescindGroupInvite(ItemStack stack) {
    Optional<String> zone = getZone(stack);
    for (Player aPlayer : Sponge.getServer().getOnlinePlayers()) {
        ItemStack[] itemStacks = tf(aPlayer).inventory.mainInventory;
        for (int i = 0; i < itemStacks.length; ++i) {
            if (hasSameZoneID(stack, itemStacks[i]) && isZoneSlaveItem(stack)) {
                if (!zone.isPresent()) {
                    aPlayer.sendMessage(
                            Text.of(TextColors.RED, "A group you were invited to has been destroyed."));
                } else {
                    aPlayer.sendMessage(Text.of(TextColors.RED,
                            "A " + zone.get() + " group you were invited to has been destroyed."));
                }/*from  ww w  .  j ava2  s  . c om*/
                itemStacks[i] = null;
            }
        }
        tf(aPlayer).inventoryContainer.detectAndSendChanges();
    }
}

From source file:net.sf.jabref.exporter.BibDatabaseWriter.java

private static List<Comparator<BibEntry>> getSaveComparators(SavePreferences preferences, MetaData metaData) {

    List<Comparator<BibEntry>> comparators = new ArrayList<>();
    Optional<SaveOrderConfig> saveOrder = getSaveOrder(preferences, metaData);

    if (!saveOrder.isPresent()) {
        // Take care, using CrossRefEntry-Comparator, that referred entries occur after referring
        // ones. Apart from crossref requirements, entries will be sorted based on their creation order,
        // utilizing the fact that IDs used for entries are increasing, sortable numbers.
        comparators.add(new CrossRefEntryComparator());
        comparators.add(new IdComparator());
    } else {/* ww w . jav  a2s  . c o m*/
        comparators.add(new CrossRefEntryComparator());

        comparators.add(new FieldComparator(saveOrder.get().sortCriteria[0]));
        comparators.add(new FieldComparator(saveOrder.get().sortCriteria[1]));
        comparators.add(new FieldComparator(saveOrder.get().sortCriteria[2]));

        comparators.add(new FieldComparator(BibEntry.KEY_FIELD));
    }

    return comparators;
}

From source file:com.ikanow.aleph2.harvest.script.utils.ScriptUtils.java

/**
 * Creates a processbuilder pointed at the given script path and adds the working dir and environment vars for you.
 * Just runs a process that does "sh <script_file_path>"
 * @param script_file_path//from  w w w.j  av  a  2 s  . c om
 * @param working_dir
 * @return
 * @throws JsonProcessingException 
 * @throws ExecutionException 
 * @throws InterruptedException 
 */
public static ProcessBuilder createProcessBuilderForScriptFile(final String script_file_path,
        final String working_dir, final Optional<Long> test_requested_num_objects,
        final Optional<Long> test_max_runtime_s, final Map<String, String> user_args,
        final IHarvestContext context, final DataBucketBean bucket, final String aleph_global_root_path)
        throws JsonProcessingException, InterruptedException, ExecutionException {
    _logger.debug("create pb for script file: " + script_file_path);

    ArrayList<String> args = new ArrayList<String>();
    args.add("sh");
    args.add(script_file_path);
    final ProcessBuilder pb = new ProcessBuilder(args);
    pb.directory(new File(working_dir)).redirectErrorStream(true);
    pb.environment().put("JAVA_OPTS", "");
    if (test_requested_num_objects.isPresent())
        pb.environment().put(ENV_TEST_NUM_OBJ, test_requested_num_objects.get().toString());
    if (test_max_runtime_s.isPresent())
        pb.environment().put(ENV_TEST_MAX_RUNTIME_S, test_max_runtime_s.get().toString());
    //add in default env vars
    final String classpath = Stream
            .concat(context.getHarvestContextLibraries(Optional.empty()).stream(),
                    context.getHarvestLibraries(Optional.of(bucket)).get().values().stream())
            .collect(Collectors.joining(":"));
    pb.environment().put(ENV_MODULE_PATH,
            context.getHarvestContextLibraries(Optional.empty()).stream().collect(Collectors.joining(":")));
    pb.environment().put(ENV_LIBRARY_PATH, context.getHarvestLibraries(Optional.of(bucket)).get().values()
            .stream().collect(Collectors.joining(":")));
    pb.environment().put(ENV_CLASS_PATH, classpath);
    pb.environment().put(ENV_BUCKET_HDFS_PATH, aleph_global_root_path + "/data" + bucket.full_name());
    pb.environment().put(ENV_BUCKET_SIGNATURE,
            BucketUtils.getUniqueSignature(bucket.full_name(), Optional.empty()));
    pb.environment().put(ENV_BUCKET_PATH, bucket.full_name());
    pb.environment().put(ENV_BUCKET_STR, BeanTemplateUtils.toJson(bucket).toString());
    //add user args   as env vars
    user_args.forEach((k, val) -> pb.environment().put(k, val));
    return pb;
}

From source file:eu.mihosoft.vrl.v3d.Edge.java

/**
 * Returns a list of all boundary paths.
 *
 * @param boundaryEdges boundary edges (all paths must be closed)
 * @return/*from w w w.j ava  2 s  .c o m*/
 */
private static List<Polygon> boundaryPaths(List<Edge> boundaryEdges) {
    List<Polygon> result = new ArrayList<>();

    boolean[] used = new boolean[boundaryEdges.size()];
    int startIndex = 0;
    Edge edge = boundaryEdges.get(startIndex);
    used[startIndex] = true;

    startIndex = 1;

    while (startIndex > 0) {
        List<Vector3d> boundaryPath = new ArrayList<>();

        while (true) {
            Edge finalEdge = edge;

            boundaryPath.add(finalEdge.p1.pos);

            System.out.print("edge: " + edge.p2.pos);

            Optional<Edge> nextEdgeResult = boundaryEdges.stream().filter(e -> finalEdge.p2.equals(e.p1))
                    .findFirst();

            if (!nextEdgeResult.isPresent()) {
                System.out.println("ERROR: unclosed path:" + " no edge found with " + finalEdge.p2);
                break;
            }

            Edge nextEdge = nextEdgeResult.get();

            int nextEdgeIndex = boundaryEdges.indexOf(nextEdge);

            if (used[nextEdgeIndex]) {
                break;
            }

            edge = nextEdge;
            System.out.println("-> edge: " + edge.p1.pos);
            used[nextEdgeIndex] = true;
        }

        if (boundaryPath.size() < 3) {
            break;
        }

        result.add(Polygon.fromPoints(boundaryPath));
        startIndex = nextUnused(used);

        if (startIndex > 0) {
            edge = boundaryEdges.get(startIndex);
            used[startIndex] = true;
        }

    }

    System.out.println("paths: " + result.size());

    return result;
}