class Neo4jImporter implements AutoCloseable {

    public void addSegments(final String dataset,
                            final List<Neuron> neuronList,
                            final LocalDateTime timeStamp) {
        LOG.info("addSegments: entry");

        String roiPropertyBaseString = " n.`%s` = TRUE,";

        final String segmentText = "MERGE (n:`" + dataset + "-Segment`{bodyId:$bodyId}) " +
                "ON CREATE SET n.bodyId = $bodyId," +
                " n:Segment," +
                " n:" + dataset + "," +
                " n.name = $name," +
                " n.type = $type," +
                " n.instance = $instance," +
                " n.primaryNeurite = $primaryNeurite," +
                " n.majorInput = $majorInput," +
                " n.majorOutput = $majorOutput," +
                " n.clonalUnit = $clonalUnit," +
                " n.neurotransmitter = $neurotransmitter," +
                " n.property = $property," +
                " n.status = $status," +
                " n.size = $size," +
                " n.somaLocation = $somaLocation," +
                " n.somaRadius = $somaRadius, " +
                "%s" + //placeholder for roi properties
                " n.timeStamp = $timeStamp";

        final String synapseSetText = "MERGE (s:`" + dataset + "-SynapseSet`{datasetBodyId:$datasetBodyId}) ON CREATE SET s.datasetBodyId=$datasetBodyId, s.timeStamp=$timeStamp, s:SynapseSet, s:" + dataset + " \n";

        final String segmentContainsSynapseSetText = "MERGE (n:`" + dataset + "-Segment`{bodyId:$bodyId}) \n" +
                "MERGE (s:`" + dataset + "-SynapseSet`{datasetBodyId:$datasetBodyId}) \n" +
                "MERGE (n)-[:Contains]->(s)";

        final String synapseSetContainsSynapseText = "MERGE (s:`" + dataset + "-Synapse`{location:$location}) \n" +
                "MERGE (t:`" + dataset + "-SynapseSet`{datasetBodyId:$datasetBodyId}) \n" +
                "MERGE (t)-[:Contains]->(s) \n";

        final String metaNodeString = "MATCH (m:Meta{dataset:$dataset}) SET " +
                "m.lastDatabaseEdit=$timeStamp";

        try (final TransactionBatch batch = getBatch()) {
            for (final Neuron neuron : neuronList) {

                // accumulates super level rois
                StringBuilder roiProperties = updateSuperRoisRoiInfoAndCreateRoiPropertyString(new HashSet<>(), new RoiInfo(), roiPropertyBaseString, neuron.getRois(), "none");

                String segmentTextWithRois = String.format(segmentText, roiProperties.toString());

                batch.addStatement(
                        new Statement(segmentTextWithRois,
                                parameters(
                                        "bodyId", neuron.getId(),
                                        "name", neuron.getName(),
                                        "type", neuron.getType(),
                                        "instance", neuron.getInstance(),
                                        "primaryNeurite", neuron.getPrimaryNeurite(),
                                        "majorInput", neuron.getMajorInput(),
                                        "majorOutput", neuron.getMajorOutput(),
                                        "clonalUnit", neuron.getClonalUnit(),
                                        "neurotransmitter", neuron.getNeurotransmitter(),
                                        "property", neuron.getProperty(),
                                        "status", neuron.getStatus(),
                                        "size", neuron.getSize(),
                                        "somaLocation", neuron.getSomaLocation(),
                                        "somaRadius", neuron.getSomaRadius(),
                                        "timeStamp", timeStamp))
                );

                if (neuron.getSynapseLocationSet().size() > 0) {
                    batch.addStatement(
                            new Statement(synapseSetText,
                                    parameters(
                                            "datasetBodyId", dataset + ":" + neuron.getId(),
                                            "timeStamp", timeStamp))
                    );

                    batch.addStatement(
                            new Statement(segmentContainsSynapseSetText,
                                    parameters(
                                            "bodyId", neuron.getId(),
                                            "datasetBodyId", dataset + ":" + neuron.getId())));

                    for (Location synapseLocation : neuron.getSynapseLocationSet()) {
                        batch.addStatement(new Statement(synapseSetContainsSynapseText,
                                parameters(
                                        "location", synapseLocation.getAsPoint(),
                                        "datasetBodyId", dataset + ":" + neuron.getId()
                                )));

                    }
                }

            }

            batch.writeTransaction();
        }

        try (final TransactionBatch batch = getBatch()) {

            batch.addStatement(new Statement(
                    metaNodeString,
                    parameters(
                            "dataset", dataset,
                            "timeStamp", timeStamp
                    )

            ));
            batch.writeTransaction();

        }

        LOG.info("addSegments: exit");
    }

    public  Neo4jImporter(final DbConfig dbConfig);
    public  Neo4jImporter(final Driver driver);

}