Example usage for java.time LocalDate of

List of usage examples for java.time LocalDate of

Introduction

In this page you can find the example usage for java.time LocalDate of.

Prototype

public static LocalDate of(int year, int month, int dayOfMonth) 

Source Link

Document

Obtains an instance of LocalDate from a year, month and day.

Usage

From source file:aajavafx.VisitorScheduleController.java

/**
 * Initializes the controller class.//from   ww w.  j av a2s .co m
 */
@Override
public void initialize(URL url, ResourceBundle rb) {
    //instead of invisible, make the text fields locked for editing at first
    schIdField.setEditable(false);
    startHours.setEditable(false);
    startMins.setEditable(false);
    startSecs.setEditable(false);
    endHours.setEditable(false);
    endHours.setEditable(false);
    endHours.setEditable(false);
    customerBox.setDisable(true);
    visitorBox.setDisable(true);
    datePicker.setDisable(true);
    repeatingBox.setDisable(true);

    schIdColumn.setCellValueFactory(cellData -> cellData.getValue().visSchIdProperty().asObject());
    custIdColumn.setCellValueFactory(cellData -> cellData.getValue().customersCuIdProperty().asObject());
    visitorIdColumn.setCellValueFactory(cellData -> cellData.getValue().visitorsVisIdProperty());
    dateColumn.setCellValueFactory(cellData -> cellData.getValue().visitStartDateProperty());
    startTimeColumn.setCellValueFactory(cellData -> cellData.getValue().visitStartTimeProperty());
    endTimeColumn.setCellValueFactory(cellData -> cellData.getValue().visitEndTimeProperty());
    repeatingColumn.setCellValueFactory(cellData -> cellData.getValue().visRepetitionCircleProperty());
    hashColumn.setCellValueFactory(cellData -> cellData.getValue().visitHashProperty());

    try {
        //Populate table

        tableVisitorSchedule.setItems(getVisitorSchedules());
        ObservableList<String> repetition = FXCollections.observableArrayList();
        repetition.add("NONE");
        repetition.add("DAILY");
        repetition.add("WEEKLY");
        repetition.add("MONTHLY");
        repeatingBox.setItems(repetition);
        customerBox.setItems(getCustomer());
        customerBox.getItems().add("Add customer");
        visitorBox.setItems(getVisitor());
        visitorBox.getItems().add("Add visitor");
    } catch (IOException ex) {
        Logger.getLogger(VisitorController.class.getName()).log(Level.SEVERE, null, ex);
    } catch (Exception ex) {
        Logger.getLogger(VisitorController.class.getName()).log(Level.SEVERE, null, ex);
    }

    tableVisitorSchedule.getSelectionModel().selectedItemProperty()
            .addListener((obs, oldSelection, newSelection) -> {
                if (newSelection != null) {
                    schIdField.setText("" + newSelection.getVisSchId());
                    String custId = newSelection.customersCuIdProperty().getValue() + ".";
                    customerBox.setValue(getCustomerStringFromID(custId));
                    String visId = newSelection.getVisitorsVisId() + ".";
                    visitorBox.setValue(getVisitorStringFromID(visId));
                    String[] parts = newSelection.getVisitStartDate().split("-");
                    LocalDate ld = LocalDate.of(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]),
                            Integer.parseInt(parts[2]));
                    datePicker.setValue((ld));
                    String[] startParts = newSelection.getVisitStartTime().split(":");
                    startHours.setText(startParts[0]);
                    startMins.setText(startParts[1]);
                    startSecs.setText(startParts[2]);
                    String[] endParts = newSelection.getVisitEndTime().split(":");
                    endHours.setText(endParts[0]);
                    endMins.setText(endParts[1]);
                    endSecs.setText(endParts[2]);
                    repeatingBox.setValue(newSelection.getVisRepetitionCircle());
                }
            });
}

From source file:de.steilerdev.myVerein.server.controller.admin.EventManagementController.java

/**
 * Returns all events, that are taking place on a specified date. The date parameter needs to be formatted according to the following pattern: YYYY/MM/DD. This function is invoked by GETting the URI /api/admin/event/date
 * @param date The selected date, correctly formatted (YYYY/MM/DD)
 * @return An HTTP response with a status code. If the function succeeds, a list of events is returned, otherwise an error code is returned.
 *//*  w  w w.  jav  a  2s .  co m*/
@RequestMapping(value = "date", produces = "application/json", method = RequestMethod.GET)
public ResponseEntity<List<Event>> getEventsOfDate(@RequestParam String date, @CurrentUser User currentUser) {
    logger.trace("[" + currentUser + "] Getting events of date " + date);
    LocalDateTime startOfDay, endOfDay, startOfMonth, endOfMonth;
    ArrayList<Event> eventsOfDay = new ArrayList<>();
    try {
        // Get start of day and start of next day
        startOfDay = LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE).atStartOfDay();
        endOfDay = startOfDay.plusDays(1);

        startOfMonth = LocalDate.of(startOfDay.getYear(), startOfDay.getMonth(), 1).atStartOfDay();
        endOfMonth = startOfMonth.plusMonths(1);
        logger.debug("[" + currentUser + "] Converted to date object: " + startOfDay.toString());
    } catch (DateTimeParseException e) {
        logger.warn("[" + currentUser + "] Unable to parse date: " + date + ": " + e.toString());
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }

    logger.debug("Getting all single day events...");
    eventsOfDay.addAll(eventRepository.findAllByStartDateTimeBetweenAndMultiDate(startOfDay, endOfDay, false));
    logger.debug("All single day events retrieved, got " + eventsOfDay.size() + " events so far");

    logger.debug("Getting all multi day events...");
    //Collecting all multi date events, that either start or end within the selected month (which means that events that are spanning over several months are not collected)
    eventsOfDay.addAll(Stream.concat(
            eventRepository.findAllByStartDateTimeBetweenAndMultiDate(startOfMonth, endOfMonth, true).stream(), //All multi date events starting within the month
            eventRepository.findAllByEndDateTimeBetweenAndMultiDate(startOfMonth, endOfMonth, true).stream()) //All multi date events ending within the month
            .distinct() //Removing all duplicated events
            .parallel()
            .filter(event -> event.getStartDate().isEqual(startOfDay.toLocalDate())
                    || event.getEndDate().isEqual(startOfDay.toLocalDate())
                    || (event.getEndDate().isAfter(endOfDay.toLocalDate())
                            && event.getStartDate().isBefore(startOfDay.toLocalDate()))) //Filter all multi date events that do not span over the date
            .collect(Collectors.toList()));
    logger.debug("All multi day events gathered, got " + eventsOfDay.size() + " events so far");

    if (eventsOfDay.isEmpty()) {
        logger.warn("[" + currentUser + "] The events list of " + date + " is empty");
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    } else {
        eventsOfDay.replaceAll(Event::getSendingObjectOnlyNameTimeId);
        logger.debug("[" + currentUser + "] Returning " + eventsOfDay.size() + " events for " + date);
        return new ResponseEntity<>(eventsOfDay, HttpStatus.OK);
    }
}

From source file:squash.booking.lambdas.core.RuleManagerTest.java

@Before
public void beforeTest() {

    // Set up the rules' booking
    ruleBookingDate = "2016-07-21"; // Thursday
    ruleBooking = new Booking(1, 2, 3, 2, "J.Power/A.Shabana");
    ruleBooking.setDate(ruleBookingDate);

    // Set up the existing test booking rules
    existingThursdayNonRecurringRule = new BookingRule(ruleBooking, false, new String[0]);
    // Tweak day-of-week to avoid clash
    String newDate = LocalDate.parse(ruleBookingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).plusDays(1)
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    ruleBooking.setDate(newDate); // Friday;
    existingFridayRecurringRuleWithoutExclusions = new BookingRule(ruleBooking, true, new String[0]);
    // Tweak day-of-week again to avoid clash
    newDate = LocalDate.parse(ruleBookingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).plusDays(2)
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    ruleBooking.setDate(newDate); // Saturday
    // Create an exclusion date
    ruleExclusionDate = "2016-09-17"; // Saturday
    existingSaturdayRecurringRuleWithExclusion = new BookingRule(ruleBooking, true,
            new String[] { ruleExclusionDate });
    existingBookingRules = new ArrayList<>();
    existingBookingRules.add(existingThursdayNonRecurringRule);
    existingBookingRules.add(existingFridayRecurringRuleWithoutExclusions);
    existingBookingRules.add(existingSaturdayRecurringRuleWithExclusion);

    // Set up mock logger
    mockLogger = mockery.mock(LambdaLogger.class);
    mockery.checking(new Expectations() {
        {/*from ww  w  .j  a v  a 2s . c o  m*/
            ignoring(mockLogger);
        }
    });
    mockBookingManager = mockery.mock(IBookingManager.class);
    mockOptimisticPersister = mockery.mock(IOptimisticPersister.class);

    // Set up mock lifecycle manager
    mockLifecycleManager = mockery.mock(ILifecycleManager.class);
    mockery.checking(new Expectations() {
        {
            ignoring(mockLifecycleManager);
        }
    });

    // Set up the rule manager
    fakeCurrentSaturdayDate = LocalDate.of(2015, 12, 24);
    fakeCurrentSaturdayDateString = fakeCurrentSaturdayDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    ruleManager = new squash.booking.lambdas.core.RuleManagerTest.TestRuleManager();
    ruleManager.setOptimisticPersister(mockOptimisticPersister);
    ruleManager.setCurrentLocalDate(fakeCurrentSaturdayDate);
    adminSnsTopicArn = "adminSnsTopicArn";
    ruleManager.setAdminSnsTopicArn(adminSnsTopicArn);

    ruleItemName = "BookingRulesAndExclusions";
}

From source file:tech.tablesaw.filters.TimeDependentFilteringTest.java

private static LocalDate randomDate() {
    Random random = new Random();
    int minDay = (int) LocalDate.of(2000, 1, 1).toEpochDay();
    int maxDay = (int) LocalDate.of(2016, 1, 1).toEpochDay();
    long randomDay = minDay + random.nextInt(maxDay - minDay);
    return LocalDate.ofEpochDay(randomDay);
}

From source file:csg.files.CSGFiles.java

@Override
public void loadData(AppDataComponent data, AppDataComponent recData, AppDataComponent schData,
        AppDataComponent projectData, AppDataComponent courseData, String filePath) throws IOException {
    // CLEAR THE OLD DATA OUT
    TAData dataManager = (TAData) data;//ww w  .  j  a  va  2s.co m
    ScheduleData schDataManager = (ScheduleData) schData;
    RecitationData recDataManager = (RecitationData) recData;
    ProjectData projectDataManager = (ProjectData) projectData;
    CourseData courseDataManager = (CourseData) courseData;
    workspace = (CSGWorkspace) app.getWorkspaceComponent();

    // LOAD THE JSON FILE WITH ALL THE DATA
    JsonObject json = loadJSONFile(filePath);

    // LOAD THE START AND END HOURS
    String startHour = json.getString(JSON_START_HOUR);
    String endHour = json.getString(JSON_END_HOUR);
    dataManager.initHours(startHour, endHour);

    // NOW RELOAD THE WORKSPACE WITH THE LOADED DATA
    app.getWorkspaceComponent().reloadWorkspace(app.getTADataComponent());

    int startDay = json.getInt(JSON_STARTDAY);
    int startMonth = json.getInt(JSON_STARTMONTH);
    int startYear = json.getInt(JSON_STARTYEAR);

    courseDataManager.setStartDay(startDay);
    courseDataManager.setStartMonth(startMonth);
    courseDataManager.setStartYear(startYear);

    if (startDay != 0 && startMonth != 0 && startYear != 0) {
        LocalDate startDate = LocalDate.of(startYear, startMonth, startDay);
        workspace.getMonStartDatePicker().setValue(startDate);
    } else {
        workspace.getMonStartDatePicker().setValue(null);
    }

    int endDay = json.getInt(JSON_ENDDAY);
    int endMonth = json.getInt(JSON_ENDMONTH);
    int endYear = json.getInt(JSON_ENDYEAR);

    courseDataManager.setEndDay(endDay);
    courseDataManager.setEndMonth(endMonth);
    courseDataManager.setEndYear(endYear);

    if (endDay != 0 && endMonth != 0 && endYear != 0) {
        LocalDate endDate = LocalDate.of(endYear, endMonth, endDay);
        workspace.getFriEndDatePicker().setValue(endDate);
    } else {
        workspace.getFriEndDatePicker().setValue(null);
    }

    // NOW LOAD ALL THE UNDERGRAD TAs
    JsonArray jsonTAArray = json.getJsonArray(JSON_UNDERGRAD_TAS);
    for (int i = 0; i < jsonTAArray.size(); i++) {
        JsonObject jsonTA = jsonTAArray.getJsonObject(i);
        String name = jsonTA.getString(JSON_NAME);
        String email = jsonTA.getString(JSON_EMAIL);
        boolean ug = jsonTA.getBoolean(JSON_UG);
        BooleanProperty isUndergrad = new SimpleBooleanProperty();
        isUndergrad.setValue(ug);
        dataManager.addTA(name, email, isUndergrad);
    }

    // AND THEN ALL THE OFFICE HOURS
    JsonArray jsonOfficeHoursArray = json.getJsonArray(JSON_OFFICE_HOURS);
    for (int i = 0; i < jsonOfficeHoursArray.size(); i++) {
        JsonObject jsonOfficeHours = jsonOfficeHoursArray.getJsonObject(i);
        String day = jsonOfficeHours.getString(JSON_DAY);
        String time = jsonOfficeHours.getString(JSON_TIME);
        String name = jsonOfficeHours.getString(JSON_NAME);
        dataManager.addOfficeHoursReservation(day, time, name);
    }

    JsonArray jsonRecitationArray = json.getJsonArray(JSON_RECITATION);
    for (int i = 0; i < jsonRecitationArray.size(); i++) {
        JsonObject jsonRec = jsonRecitationArray.getJsonObject(i);
        String section = jsonRec.getString(JSON_SECTION);
        String instructor = jsonRec.getString(JSON_INSTRUCTOR);
        String dayTime = jsonRec.getString(JSON_DAYTIME);
        String location = jsonRec.getString(JSON_LOCATION);
        String firstTA = jsonRec.getString(JSON_FIRSTTA);
        String secondTA = jsonRec.getString(JSON_SECONDTA);
        recDataManager.addRecitation(section, instructor, dayTime, location, firstTA, secondTA);
    }

    JsonArray jsonScheduleArray = json.getJsonArray(JSON_SCHEDULEITEM);
    for (int i = 0; i < jsonScheduleArray.size(); i++) {
        JsonObject jsonSch = jsonScheduleArray.getJsonObject(i);
        String type = jsonSch.getString(JSON_TYPE);
        int month = jsonSch.getInt(JSON_MONTH);
        int day = jsonSch.getInt(JSON_DAY);
        int year = jsonSch.getInt(JSON_YEAR);
        String time = jsonSch.getString(JSON_TIME);
        String title = jsonSch.getString(JSON_TITLE);
        String topic = jsonSch.getString(JSON_TOPIC);
        String link = jsonSch.getString(JSON_LINK);
        String criteria = jsonSch.getString(JSON_CRITERIA);
        schDataManager.addScheduleItem(type, LocalDate.of(year, month, day), time, title, topic, link,
                criteria);
    }

    JsonArray jsonTeamArray = json.getJsonArray(JSON_TEAMS);
    for (int i = 0; i < jsonTeamArray.size(); i++) {
        JsonObject jsonTeam = jsonTeamArray.getJsonObject(i);
        String name = jsonTeam.getString(JSON_NAME);
        String color = jsonTeam.getString(JSON_COLOR);
        String textColor = jsonTeam.getString(JSON_TEXTCOLOR);
        String link = jsonTeam.getString(JSON_LINK);
        projectDataManager.addTeam(name, color, textColor, link);
    }

    JsonArray jsonStudentArray = json.getJsonArray(JSON_STUDENTS);
    for (int i = 0; i < jsonStudentArray.size(); i++) {
        JsonObject jsonStudent = jsonStudentArray.getJsonObject(i);
        String firstName = jsonStudent.getString(JSON_FIRSTNAME);
        String lastName = jsonStudent.getString(JSON_LASTNAME);
        String team = jsonStudent.getString(JSON_TEAM);
        String role = jsonStudent.getString(JSON_ROLE);
        projectDataManager.addStudent(firstName, lastName, team, role);
    }

    JsonArray jsonTemplateArray = json.getJsonArray(JSON_COURSETEMPLATE);
    courseDataManager.getTemplates().clear();
    for (int i = 0; i < jsonTemplateArray.size(); i++) {
        JsonObject jsonTemplate = jsonTemplateArray.getJsonObject(i);
        boolean use = jsonTemplate.getBoolean(JSON_USE);
        String navbar = jsonTemplate.getString(JSON_NAVBAR);
        String fileName = jsonTemplate.getString(JSON_FILENAME);
        String script = jsonTemplate.getString(JSON_SCRIPT);
        courseDataManager.addTemplate(use, navbar, fileName, script);
    }

    JsonObject courseJson = json.getJsonObject(JSON_COURSE);
    courseDataManager.setNumber(courseJson.getString(JSON_NUMBER));
    courseDataManager.setSemester(courseJson.getString(JSON_SEMESTER));
    courseDataManager.setSubject(courseJson.getString(JSON_SUBJECT));
    courseDataManager.setYear(courseJson.getString(JSON_YEAR));
    courseDataManager.setTitle(courseJson.getString(JSON_TITLE));
    courseDataManager.setInsName(courseJson.getString(JSON_INSTRUCTORNAME));
    courseDataManager.setInsHome(courseJson.getString(JSON_INSTRUCTORHOME));
    courseDataManager.setBannerLink(courseJson.getString(JSON_BANNER));
    courseDataManager.setLeftFooterLink(courseJson.getString(JSON_LEFTFOOTER));
    courseDataManager.setRightFooterLink(courseJson.getString(JSON_RIGHTFOOTER));
    courseDataManager.setTemplateDir(courseJson.getString(JSON_TEMPLATEDIR));
    courseDataManager.setExportDir(courseJson.getString(JSON_EXPORTDIR));
    courseDataManager.setStyleSheet(courseJson.getString(JSON_STYLESHEET));

    workspace.getSubjectCombo().setValue(courseDataManager.getSubject());
    workspace.getNumCombo().setValue(courseDataManager.getNumber());
    workspace.getSemCombo().setValue(courseDataManager.getSemester());
    workspace.getYearCombo().setValue(courseDataManager.getYear());
    workspace.getTitleTextField().setText(courseDataManager.getTitle());
    workspace.getInsNameTextField().setText(courseDataManager.getInsName());
    workspace.getInsHomeTextField().setText(courseDataManager.getInsHome());
    workspace.getStyleSheetCombo().setValue(courseDataManager.getStyleSheet());

    if (!courseDataManager.getBannerLink().isEmpty()) {
        FileInputStream bannerLocation = new FileInputStream(courseJson.getString(JSON_BANNER));
        Image newImg = new Image(bannerLocation);
        workspace.getBannerImage().setImage(newImg);
    } else {
        workspace.getBannerImage().setImage(null);
    }

    if (!courseDataManager.getLeftFooterLink().isEmpty()) {
        FileInputStream leftFooterLocation = new FileInputStream(courseJson.getString(JSON_LEFTFOOTER));
        Image newImg2 = new Image(leftFooterLocation);
        workspace.getLeftFooterImage().setImage(newImg2);
    } else {
        workspace.getLeftFooterImage().setImage(null);
    }

    if (!courseDataManager.getRightFooterLink().isEmpty()) {
        FileInputStream rightFooterLocation = new FileInputStream(courseJson.getString(JSON_RIGHTFOOTER));
        Image newImg3 = new Image(rightFooterLocation);
        workspace.getRightFooterImage().setImage(newImg3);
    } else {
        workspace.getRightFooterImage().setImage(null);
    }
    workspace.getCourseTemplateLocLabel().setText(courseJson.getString(JSON_TEMPLATEDIR));
    workspace.getExportLabel().setText(courseJson.getString(JSON_EXPORTDIR));

}

From source file:massbank.RecordParserDefinition.java

public RecordParserDefinition(Record callback) {
    def("start", ref("accession").seq(ref("record_title")).seq(ref("date")).seq(ref("authors"))
            .seq(ref("license")).seq(ref("copyright").optional()).seq(ref("publication").optional())
            .seq(ref("comment").optional()).seq(ref("ch_name")).seq(ref("ch_compound_class"))
            .seq(ref("ch_formula")).seq(ref("ch_exact_mass")).seq(ref("ch_smiles")).seq(ref("ch_iupac"))
            .seq(ref("ch_link").optional()).seq(ref("sp_scientific_name").optional())
            .seq(ref("sp_lineage").optional()).seq(ref("sp_link").optional()).seq(ref("sp_sample").optional())
            .seq(ref("ac_instrument")).seq(ref("ac_instrument_type")).seq(ref("ac_mass_spectrometry_ms_type"))
            .seq(ref("ac_mass_spectrometry_ion_mode")).seq(ref("ac_mass_spectrometry").optional())
            .seq(ref("ac_chromatography").optional()).seq(ref("ms_focused_ion").optional())
            .seq(ref("ms_data_processing").optional()).seq(ref("pk_splash"))
            .seq(ref("pk_annotation").optional()).seq(ref("pk_num_peak")).seq(ref("pk_peak")).seq(ref("endtag"))
            //         .map((List<?> value) -> {
            //            System.out.println(value);
            //            return value;                  
            //         })
            .end());/*  w ww.j av  a2 s . co m*/

    // 1.1 Syntax Rules
    // Single line information is either one of the followings:
    // Tag : space Value ( ; space Value)
    // Tag : space subtag space Value ( ; space Value)
    // Multiple line information
    // First line is Tag: space
    // Following lines are space space Value
    // Last line of a MassBank Record is // .
    def("tagsep", StringParser.of(": "));
    def("valuesep", StringParser.of("; "));
    def("endtag", StringParser.of("//").trim());
    def("multiline_start", StringParser.of("  "));

    // 2.1 Record Specific Information
    // 2.1.1 ACCESSION
    // Identifier of the MassBank Record. Mandatory
    // Example
    // ACCESSION: ZMS00006
    // 8-character fix-length string.
    // Prefix two or three alphabetical capital characters.
    def("accession", StringParser.of("ACCESSION").seq(ref("tagsep"))
            .seq(letter().times(2).flatten().seq(digit().times(6).flatten()).map((List<String> value) -> {
                callback.ACCESSION(value.get(0) + value.get(1));
                return value;
            }).or(letter().times(3).flatten().seq(digit().times(5).flatten()).map((List<String> value) -> {
                callback.ACCESSION(value.get(0) + value.get(1));
                return value;
            }))).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.1.2 RECORD_TITLE (CH$NAME ; AC$INSTRUMENT_TYPE ; AC$MASS_SPECTROMETRY: MS_TYPE)
    // Brief Description of MassBank Record. Mandatory
    // Example: RECORD_TITLE: (-)-Nicotine; ESI-QQ; MS2; CE 40 V; [M+H]+
    // It consists of the values of CH$NAME; AC$INSTRUMENT_TYPE; AC$MASS_SPECTROMETRY: MS_TYPE;.
    def("record_title",
            StringParser.of("RECORD_TITLE").seq(ref("tagsep"))
                    .seq(ref("ch_name_value").seq(ref("valuesep")).pick(0))
                    .seq(ref("ac_instrument_type_value").seq(ref("valuesep")).pick(0))
                    .seq(ref("ac_mass_spectrometry_ms_type_value"))
                    // TODO curation required because ionisation energy is not in format doc
                    .seq(ref("valuesep").seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten())
                            .pick(1).optional())
                    .seq(Token.NEWLINE_PARSER).map((List<?> value) -> {
                        //System.out.println(value);
                        if (value.get(value.size() - 2) == null)
                            callback.RECORD_TITLE(value.subList(2, value.size() - 2).toString());
                        else
                            callback.RECORD_TITLE(value.subList(2, value.size() - 1).toString());
                        return value;
                    }));

    // 2.1.3 DATE
    // Date of the Creation or the Last Modification of MassBank Record. Mandatory
    // Example
    // DATE: 2011.02.21 (Created 2007.07.07)
    // DATE: 2016.01.15
    // DATE: 2016.01.19 (Created 2006.12.21, modified 2011.05.06)
    def("date_value", CharacterParser.digit().times(4).flatten().trim(CharacterParser.of('.'))
            .map((String value) -> Integer.parseInt(value))
            .seq(CharacterParser.digit().times(2).flatten().trim(CharacterParser.of('.'))
                    .map((String value) -> Integer.parseInt(value)))
            .seq(CharacterParser.digit().times(2).flatten().map((String value) -> Integer.parseInt(value)))
            .map((List<Integer> value) -> {
                return LocalDate.of(value.get(0), value.get(1), value.get(2));
            }));
    def("date",
            StringParser.of("DATE").seq(ref("tagsep")).seq(ref("date_value"))
                    .seq(ref("date_value").trim(StringParser.of(" (Created "), StringParser.of(", modified "))
                            .seq(ref("date_value").trim(CharacterParser.none(), CharacterParser.of(')')))
                            .or(ref("date_value").trim(StringParser.of(" (Created "), CharacterParser.of(')')))
                            .optional())
                    .seq(Token.NEWLINE_PARSER).map((List<?> value) -> {
                        //System.out.println(value);
                        callback.DATE((LocalDate) value.get(2));
                        return value;
                    }));

    // 2.1.4 AUTHORS
    // Authors and Affiliations of MassBank Record. Mandatory
    // Example
    // AUTHORS: Akimoto N, Grad Sch Pharm Sci, Kyoto Univ and Maoka T, Res Inst Prod Dev.
    // Only single-byte characters are allowed.  For example,  is not allowed.
    def("authors", StringParser.of("AUTHORS").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                callback.AUTHORS(value);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.1.5 LICENSE
    // License of MassBank Record. Mandatory
    // Example
    // LICENSE: CC BY
    // TODO fix format doc
    def("license", StringParser.of("LICENSE").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                callback.LICENSE(value);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.1.6 COPYRIGHT
    // Copyright of MassBank Record. Optional
    // Example
    // COPYRIGHT: Keio University
    def("copyright", StringParser.of("COPYRIGHT").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                callback.COPYRIGHT(value);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.1.7 PUBLICATION
    // Reference of the Mass Spectral Data. Optional
    // Example
    // PUBLICATION: Iida T, Tamura T, et al, J Lipid Res. 29, 165-71 (1988). [PMID: 3367086]
    // Citation with PubMed ID is recommended.
    def("publication", StringParser.of("PUBLICATION").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                callback.PUBLICATION(value);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.1.8 COMMENT
    // Comments.   Optional and Iterative 
    // In MassBank, COMMENT fields are often used to show the relations of the present record with other MassBank
    // records and with data files. In these cases, the terms in brackets [ and ] are reserved for the comments
    // specific to the following five examples.
    // Example 1
    // COMMENT: This record is a MS3 spectrum. Link to the MS2 spectrum is added in the following comment field.
    // COMMENT: [MS2] KO008089
    // Example 2
    // COMMENT: This record was generated by merging the following three MassBank records.
    // COMMENT: [Merging] KO006229 Tiglate; ESI-QTOF; MS2; CE:10 V [M-H]-.
    // COMMENT: [Merging] KO006230 Tiglate; ESI-QTOF; MS2; CE:20 V [M-H]-.
    // COMMENT: [Merging] KO006231 Tiglate; ESI-QTOF; MS2; CE:30 V [M-H]-.
    // Example 3
    // COMMENT: This record was merged into a MassBank record, KOX00012, with other records.
    // COMMENT: [Merged] KOX00012
    // Example 4
    // COMMENT: Analytical conditions of LC-MS were described in separate files.
    // COMMENT: [Mass spectrometry] ms1.txt
    // COMMENT: [Chromatography] lc1.txt.
    // Example 5
    // COMMENT: Profile spectrum of this record is given as a JPEG file.
    // COMMENT: [Profile] CA000185.jpg
    def("comment",
            StringParser.of("COMMENT").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
                    .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten())
                    .seq(Token.NEWLINE_PARSER).pick(3).plus().map((List<String> value) -> {
                        callback.COMMENT(value);
                        return value;
                    }));

    // 2.2.1 CH$NAME
    // Name of the Chemical Compound Analyzed. Mandatory and Iterative
    // Example
    // CH$NAME: D-Tartaric acid
    // CH$NAME: (2S,3S)-Tartaric acid
    // No prosthetic molecule of adducts (HCl, H2SO3, H2O, etc), conjugate ions (Chloride, etc) , and 
    // protecting groups (TMS, etc.) is included.
    // Chemical names which are listed in the compound list are recommended.  Synonyms could be added.
    // If chemical compound is a stereoisomer, stereochemistry should be indicated.
    // TODO no ';' in CH$NAME
    def("ch_name_value", CharacterParser.word().or(CharacterParser.anyOf("-+, ()[]{}/.:$^'`_*?<>#;"))
            .plusLazy(ref("valuesep").or(Token.NEWLINE_PARSER)).flatten());
    def("ch_name", StringParser.of("CH$NAME").seq(ref("tagsep")).seq(ref("ch_name_value"))
            .seq(Token.NEWLINE_PARSER).pick(2).plus().map((List<String> value) -> {
                //System.out.println(value);
                callback.CH_NAME(value);
                return value;
            }));

    // 2.2.2 CH$COMPOUND_CLASS
    // Category of Chemical Compound. Mandatory
    // Example
    // CH$COMPOUND_CLASS: Natural Product; Carotenoid; Terpenoid; Lipid
    // Either Natural Product or Non-Natural Product should be precedes the other class names .
    def("ch_compound_class", StringParser.of("CH$COMPOUND_CLASS").seq(ref("tagsep"))
            .seq(CharacterParser.word().or(CharacterParser.anyOf("-+,()[]{}/.:$^'`_*?<> ")).plus().flatten())
            .seq(ref("valuesep").seq(
                    CharacterParser.word().or(CharacterParser.anyOf("-+,()[]{}/.:$^'`_*?<> ")).plus().flatten())
                    .pick(1).star())
            .seq(Token.NEWLINE_PARSER).map((List<?> value) -> {
                @SuppressWarnings("unchecked")
                List<String> list = (List<String>) value.get(3);
                list.add(0, (String) value.get(2));
                callback.CH_COMPOUND_CLASS(list);
                return value;
            }));

    // 2.2.3 CH$FORMULA
    // Molecular Formula of Chemical Compound. Mandatory
    // Example
    // CH$FORMULA: C9H10ClNO3
    // It follows the Hill's System.
    // No prosthetic molecule is included (see 2.2.1 CH$NAME).
    // Molecular formulae of derivatives by chemical modification with TMS, etc. should be given in the MS$FOCUSED_ION: DERIVATIVE_FORM (2.5.1) field.
    def("ch_formula", StringParser.of("CH$FORMULA").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                IMolecularFormula m = MolecularFormulaManipulator.getMolecularFormula((String) value,
                        DefaultChemObjectBuilder.getInstance());
                callback.CH_FORMULA(m);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value.toString());
    //            return value;                  
    //         })
    );

    // 2.2.4 CH$EXACT_MASS
    // Monoisotopic Mass of Chemical Compound. Mandatory
    // Example
    // CH$EXACT_MASS: 430.38108
    // A value with 5 digits after the decimal point is recommended.
    def("number", digit().plus().seq(CharacterParser.of('.').seq(digit().plus()).optional())
            .seq(CharacterParser.anyOf("eE").seq(digit().plus()).optional()).flatten());

    def("ch_exact_mass",
            StringParser.of("CH$EXACT_MASS").seq(ref("tagsep")).seq(ref("number").map((String value) -> {
                Double d = Double.parseDouble(value);
                callback.CH_EXACT_MASS(d);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value.toString());
    //            return value;                  
    //         })
    );

    // 2.2.5 CH$SMILES *
    // SMILES String. Mandatory
    // Example
    // CH$SMILES: NCC(O)=O
    // Isomeric SMILES but not a canonical one.
    def("ch_smiles",
            StringParser.of("CH$SMILES").seq(ref("tagsep"))
                    .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten()
                            // call a Continuation Parser to validate content of SMILES string
                            .callCC((Function<Context, Result> continuation, Context context) -> {
                                Result r = continuation.apply(context);
                                if (r.isSuccess()) {
                                    try {
                                        if (r.get().equals("N/A"))
                                            callback.CH_SMILES(new AtomContainer());
                                        else
                                            callback.CH_SMILES(
                                                    new SmilesParser(DefaultChemObjectBuilder.getInstance())
                                                            .parseSmiles(r.get()));
                                    } catch (InvalidSmilesException e) {
                                        return r = context.failure(
                                                "Can not parse SMILES string in \"CH$SMILES\" field.\nError: "
                                                        + e.getMessage() + " for " + r.get());
                                    }
                                }
                                return r;
                            }))
                    .seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value.toString());
    //            return value;                  
    //         })
    );

    // 2.2.6 CH$IUPAC *
    // IUPAC International Chemical Identifier (InChI Code). Mandatory
    // Example
    // CH$IUPAC: InChI=1S/C2H5NO2/c3-1-2(4)5/h1,3H2,(H,4,5)
    // Not IUPAC name.
    def("ch_iupac",
            StringParser.of("CH$IUPAC").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
                    .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten()
                            // call a Continuation Parser to validate content of InChi string
                            .callCC((Function<Context, Result> continuation, Context context) -> {
                                Result r = continuation.apply(context);
                                if (r.isSuccess()) {
                                    try {
                                        if (r.get().equals("N/A"))
                                            callback.CH_IUPAC(new AtomContainer());
                                        else {
                                            // Get InChIToStructure
                                            InChIToStructure intostruct = InChIGeneratorFactory.getInstance()
                                                    .getInChIToStructure(r.get(),
                                                            DefaultChemObjectBuilder.getInstance());
                                            INCHI_RET ret = intostruct.getReturnStatus();
                                            if (ret == INCHI_RET.WARNING) {
                                                // Structure generated, but with warning message
                                                System.out.println("InChI warning: " + intostruct.getMessage());
                                                System.out.println(callback.ACCESSION());
                                            } else if (ret != INCHI_RET.OKAY) {
                                                // Structure generation failed
                                                return context.failure(
                                                        "Can not parse INCHI string in \"CH$IUPAC\" field. Structure generation failed: "
                                                                + ret.toString() + " ["
                                                                + intostruct.getMessage() + "] for " + r.get());
                                            }
                                            IAtomContainer m = intostruct.getAtomContainer();
                                            callback.CH_IUPAC(m);
                                        }
                                    } catch (CDKException e) {
                                        return context
                                                .failure("\"Can not parse INCHI string in \"CH$IUPAC\" field.");
                                    }
                                }
                                return r;
                            }))
                    .seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value.toString());
    //            return value;                  
    //         })
    );

    // TODO no record implements CH$CDK_DEPICT
    // 2.2.7 CH$CDK_DEPICT

    // 2.2.8 CH$LINK: subtag  identifier
    // Identifier and Link of Chemical Compound to External Databases.
    // Optional and Iterative
    // Example
    // CH$LINK: CAS 56-40-6
    // CH$LINK: COMPTOX DTXSID50274017
    // CH$LINK: INCHIKEY UFFBMTHBGFGIHF-UHFFFAOYSA-N
    // CH$LINK: KEGG C00037
    // CH$LINK: PUBCHEM SID: 11916 CID:182232
    // CH$LINK fields should be arranged by the alphabetical order of database names.
    def("ch_link_subtag", StringParser.of("CAS ").or(StringParser.of("CAYMAN ")).or(StringParser.of("CHEBI "))
            .or(StringParser.of("CHEMPDB ")).or(StringParser.of("CHEMSPIDER ")).or(StringParser.of("COMPTOX "))
            .or(StringParser.of("HMDB ")).or(StringParser.of("INCHIKEY ")).or(StringParser.of("KAPPAVIEW "))
            .or(StringParser.of("KEGG ")).or(StringParser.of("KNAPSACK ")).or(StringParser.of("LIPIDBANK "))
            .or(StringParser.of("LIPIDMAPS ")).or(StringParser.of("NIKKAJI ")).or(StringParser.of("PUBCHEM ")));
    def("ch_link", StringParser.of("CH$LINK").seq(ref("tagsep")).seq(ref("ch_link_subtag"))
            .seq(Token.NEWLINE_PARSER.not()).pick(2)
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten()).map((List<String> value) -> {
                return Pair.of(value.get(0).trim(), value.get(1));
            }).seq(Token.NEWLINE_PARSER).pick(0).plus().map((List<Pair<String, String>> value) -> {
                //            System.out.println(value);
                callback.CH_LINK(value);
                return value;
            }));

    // 2.3.1 SP$SCIENTIFIC_NAME
    // Scientific Name of Biological Species, from Which Sample was Prepared.  Optional
    // Example
    // SP$SCIENTIFIC_NAME: Mus musculus
    def("sp_scientific_name",
            StringParser.of("SP$SCIENTIFIC_NAME").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
                    .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                        callback.SP_SCIENTIFIC_NAME(value);
                        return value;
                    })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.3.2 SP$LINEAGE
    // Evolutionary lineage of the species, from which the sample was prepared. Optional
    // Example: SP$LINEAGE: cellular organisms; Eukaryota; Fungi/Metazoa group; Metazoa; Eumetazoa; Bilateria; Coelomata; Deuterostomia; Chordata; Craniata; Vertebrata; Gnathostomata; Teleostomi; Euteleostomi; Sarcopterygii; Tetrapoda; Amniota; Mammalia; Theria; Eutheria; Euarchontoglires; Glires; Rodentia; Sciurognathi; Muroidea; Muridae; Murinae; Mus
    def("sp_lineage", StringParser.of("SP$LINEAGE").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                callback.SP_LINEAGE(value);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.3.3 SP$LINK subtag identifier
    // Identifier of Biological Species in External Databases.  Optional and iterative
    // Example
    // SP$LINK: NCBI-TAXONOMY 10090
    def("sp_link", StringParser.of("SP$LINK").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
            .seq(CharacterParser.any().plusLazy(CharacterParser.whitespace()).flatten())
            .seq(CharacterParser.whitespace()).pick(3)
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten()).map((List<String> value) -> {
                return Pair.of(value.get(0).trim(), value.get(1));
            }).seq(Token.NEWLINE_PARSER).pick(0).plus().map((List<Pair<String, String>> value) -> {
                //System.out.println(value);
                callback.SP_LINK(value);
                return value;
            }));

    // 2.3.4 SP$SAMPLE
    // Tissue or Cell, from which Sample was Prepared. Optional and iterative
    // Example
    // SP$SAMPLE: Liver extracts
    def("sp_sample",
            StringParser.of("SP$SAMPLE").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
                    .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten())
                    .seq(Token.NEWLINE_PARSER).pick(3).plus().map((List<String> value) -> {
                        //System.out.println(value);
                        callback.SP_SAMPLE(value);
                        return value;
                    }));

    // 2.4.1 AC$INSTRUMENT
    // Commercial Name and Model of Chromatographic Separation Instrument,
    // if any were coupled, and Mass Spectrometer and Manufacturer. Mandatory
    // Example: AC$INSTRUMENT: LC-10ADVPmicro HPLC, Shimadzu; LTQ Orbitrap, Thermo Electron.
    // Cross-reference to mzOntology: Instrument model [MS:1000031] All the instruments
    // are given together in a single line. This record is not iterative.
    def("ac_instrument", StringParser.of("AC$INSTRUMENT").seq(ref("tagsep")).seq(Token.NEWLINE_PARSER.not())
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                callback.AC_INSTRUMENT(value);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.4.2 AC$INSTRUMENT_TYPE
    // General Type of Instrument. Mandatory
    // Example
    // AC$INSTRUMENT_TYPE: LC-ESI-QTOF
    // Format is:
    // (Separation tool type-)Ionization method-Ion analyzer type(Ion analyzer type).
    // Separation tool types are CE, GC, LC.
    // Ionization methods are APCI, APPI, EI, ESI, FAB, MALDI.
    // Ion analyzer types are B, E, FT, IT, Q, TOF.
    // In tandem mass analyzers, no  is inserted between ion analyzers.
    // FT includes FTICR and other type analyzers using FT, such as Orbitrap(R).
    // IT comprises quadrupole ion trap analyzers such as 3D ion trap and linear ion trap.
    // Other examples of AC$INSTRUMENT_TYPE data are as follows.
    // ESI-QQ
    // ESI-QTOF
    // GC-EI-EB
    // LC-ESI-ITFT
    // Cross-reference to mzOntology: Ionization methods [MS:1000008]; APCI [MS:1000070]; APPI [MS:1000382]; EI [MS:1000389]; ESI [MS:1000073]; B [MS:1000080]; IT [MS:1000264], Q [MS:1000081], TOF [MS:1000084].
    def("ac_instrument_type_sep", StringParser.of("CE").or(StringParser.of("GC")).or(StringParser.of("LC"))
            .seq(CharacterParser.of('-')).pick(0));
    def("ac_instrument_type_ionisation",
            StringParser.of("APCI").or(StringParser.of("APPI")).or(StringParser.of("EI"))
                    .or(StringParser.of("ESI")).or(StringParser.of("FAB")).or(StringParser.of("MALDI"))
                    .or(StringParser.of("FD")).or(StringParser.of("CI")).or(StringParser.of("FI"))
                    .seq(CharacterParser.of('-')).pick(0));
    def("ac_instrument_type_analyzer", StringParser.of("B").or(StringParser.of("E")).or(StringParser.of("FT"))
            .or(StringParser.of("IT")).or(StringParser.of("Q")).or(StringParser.of("TOF")));
    def("ac_instrument_type_value", ref("ac_instrument_type_sep").optional()
            .seq(ref("ac_instrument_type_ionisation")).seq(ref("ac_instrument_type_analyzer").plus()));
    def("ac_instrument_type", StringParser.of("AC$INSTRUMENT_TYPE").seq(ref("tagsep"))
            .seq(ref("ac_instrument_type_value").map((List<?> value) -> {
                //               System.out.println(value);

                List<String> list = new ArrayList<String>();
                for (int idx = 0; idx < value.size(); idx++) {
                    if (value.get(idx) instanceof String)
                        // string
                        list.add((String) value.get(idx));
                    if (value.get(idx) instanceof List)
                        // list of strings
                        list.addAll((List<String>) value.get(idx));
                }
                String ac_instrument_type_konkat = String.join("-", list.toArray(new String[list.size()]));

                callback.AC_INSTRUMENT_TYPE(ac_instrument_type_konkat);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.4.3 AC$MASS_SPECTROMETRY: MS_TYPE
    // Data Type.   Mandatory
    // Example
    // AC$MASS_SPECTROMETRY: MS_TYPE MS2
    // Either of MS, MS2, MS3, MS4, , , .
    // Brief definition of terms used in MS_TYPE
    // MS2  is 1st generation product ion spectrum(of MS)
    // MS3  is 2nd generation product ion spectrum(of MS)
    // MS2  is the precursor ion spectrum of MS3
    // IUPAC Recommendations 2006 (http://old.iupac.org/reports/provisional/abstract06/murray_prs.pdf)
    def("ac_mass_spectrometry_ms_type_value", StringParser.of("MS4").or(StringParser.of("MS3"))
            .or(StringParser.of("MS2")).or(StringParser.of("MS")));
    def("ac_mass_spectrometry_ms_type",
            StringParser.of("AC$MASS_SPECTROMETRY").seq(ref("tagsep")).seq(StringParser.of("MS_TYPE "))
                    .seq(ref("ac_mass_spectrometry_ms_type_value").map((String value) -> {
                        callback.AC_MASS_SPECTROMETRY_MS_TYPE(value);
                        return value;
                    })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.4.4 AC$MASS_SPECTROMETRY: ION_MODE
    // Polarity of Ion Detection. Mandatory
    // Example: AC$MASS_SPECTROMETRY: ION_MODE POSITIVE
    // Either of POSITIVE or NEGATIVE is allowed. Cross-reference to mzOntology: POSITIVE [MS:1000030] 
    // or NEGATIVE [MS:1000129]; Ion mode [MS:1000465]
    def("ac_mass_spectrometry_ion_mode_value", StringParser.of("POSITIVE").or(StringParser.of("NEGATIVE")));
    def("ac_mass_spectrometry_ion_mode",
            StringParser.of("AC$MASS_SPECTROMETRY").seq(ref("tagsep")).seq(StringParser.of("ION_MODE "))
                    .seq(ref("ac_mass_spectrometry_ion_mode_value").map((String value) -> {
                        callback.AC_MASS_SPECTROMETRY_ION_MODE(value);
                        return value;
                    })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //         System.out.println(value);
    //         return value;                  
    //         })
    );

    // 2.4.5 AC$MASS_SPECTROMETRY: subtag Description
    // Other Experimental Methods and Conditions of Mass Spectrometry. Optional
    // Description is a list of numerical values with/without unit or a sentence. 
    // AC$MASS_SPECTROMETRY fields should be arranged by the alphabetical order of subtag names.
    // 2.4.5 Subtag: COLLISION_ENERGY
    // Collision Energy for Dissociation.
    // Example 1: AC$MASS_SPECTROMETRY: COLLISION_ENERGY 20 kV 
    // Example 2: AC$MASS_SPECTROMETRY: COLLISION_ENERGY Ramp 10-50 kV
    // 2.4.5 Subtag: COLLISION_GAS
    // Name of Collision Gas.
    // Example: AC$MASS_SPECTROMETRY: COLLISION_GAS N2
    // Cross-reference to mzOntology: Collision gas [MS:1000419]
    // 2.4.5 Subtag: DATE
    // Date of Analysis.
    // 2.4.5 Subtag: DESOLVATION_GAS_FLOW
    // Flow Rate of Desolvation Gas.
    // Example: AC$MASS_SPECTROMETRY: DESOLVATION_GAS_FLOW 600.0 l/h
    // 2.4.5 Subtag: DESOLVATION_TEMPERATURE
    // Temperature of Desolvation Gas.
    // Example: AC$MASS_SPECTROMETRY: DESOLVATION_TEMPERATURE 400 C
    // 2.4.5 Subtag: IONIZATION_ENERGY
    // Energy of Ionization.
    // Example: AC$MASS_SPECTROMETRY: IONIZATION_ENERGY 70 eV
    // 2.4.5 Subtag: LASER
    // Desorption /Ionization Conditions in MALDI.
    // Example: AC$MASS_SPECTROMETRY: LASER 337 nm nitrogen laser, 20 Hz, 10 nsec
    // 2.4.5 Subtag: MATRIX
    // Matrix Used in MALDI and FAB.
    // Example: AC$MASS_SPECTROMETRY: MATRIX 1-2 uL m-NBA
    // 2.4.5. Subtag : MASS_ACCURACY
    // Relative Mass Accuracy.
    // Example: AC$MASS_SPECTROMETRY: MASS_ACCURACY 50 ppm over a range of about m/z 100-1000
    // 2.4.5 Subtag: REAGENT_GAS
    // Name of Reagent Gas.
    // Example: AC$MASS_SPECTROMETRY: REAGENT_GAS ammonia
    // 2.4.5 Subtag: SCANNING
    // Scan Cycle and Range.
    // Example: AC$MASS_SPECTROMETRY: SCANNING 0.2 sec/scan (m/z 50-500)
    def("ac_mass_spectrometry_subtag",
            StringParser.of("ACTIVATION_PARAMETER ").or(StringParser.of("ACTIVATION_TIME "))
                    .or(StringParser.of("ATOM_GUN_CURRENT ")).or(StringParser.of("AUTOMATIC_GAIN_CONTROL "))
                    .or(StringParser.of("BOMBARDMENT ")).or(StringParser.of("CAPILLARY_TEMPERATURE "))
                    .or(StringParser.of("CAPILLARY_VOLTAGE "))
                    .or(StringParser.of("CDL_SIDE_OCTOPOLES_BIAS_VOLTAGE "))
                    .or(StringParser.of("CDL_TEMPERATURE ")).or(StringParser.of("COLLISION_ENERGY "))
                    .or(StringParser.of("COLLISION_GAS ")).or(StringParser.of("DATAFORMAT "))
                    .or(StringParser.of("DATE ")).or(StringParser.of("DESOLVATION_GAS_FLOW "))
                    .or(StringParser.of("DESOLVATION_TEMPERATURE ")).or(StringParser.of("DRY_GAS_FLOW "))
                    .or(StringParser.of("DRY_GAS_TEMP ")).or(StringParser.of("FRAGMENTATION_METHOD "))
                    .or(StringParser.of("FRAGMENTATION_MODE ")).or(StringParser.of("FRAGMENT_VOLTAGE "))
                    .or(StringParser.of("GAS_PRESSURE ")).or(StringParser.of("HELIUM_FLOW "))
                    .or(StringParser.of("INTERFACE_VOLTAGE ")).or(StringParser.of("IONIZATION "))
                    .or(StringParser.of("IONIZATION_ENERGY ")).or(StringParser.of("IONIZATION_POTENTIAL "))
                    .or(StringParser.of("IONIZATION_VOLTAGE ")).or(StringParser.of("ION_GUIDE_PEAK_VOLTAGE "))
                    .or(StringParser.of("ION_GUIDE_VOLTAGE ")).or(StringParser.of("ION_SOURCE_TEMPERATURE "))
                    .or(StringParser.of("ION_SPRAY_VOLTAGE ")).or(StringParser.of("ISOLATION_WIDTH "))
                    .or(StringParser.of("IT_SIDE_OCTOPOLES_BIAS_VOLTAGE ")).or(StringParser.of("LASER "))
                    .or(StringParser.of("LENS_VOLTAGE ")).or(StringParser.of("MASS_ACCURACY "))
                    .or(StringParser.of("MASS_RANGE_M/Z ")).or(StringParser.of("MATRIX "))
                    .or(StringParser.of("MASS_ACCURACY ")).or(StringParser.of("NEBULIZER "))
                    .or(StringParser.of("NEBULIZING_GAS ")).or(StringParser.of("NEEDLE_VOLTAGE "))
                    .or(StringParser.of("OCTPOLE_VOLTAGE ")).or(StringParser.of("ORIFICE_TEMP "))
                    .or(StringParser.of("ORIFICE_TEMPERATURE ")).or(StringParser.of("ORIFICE_VOLTAGE "))
                    .or(StringParser.of("PEAK_WIDTH ")).or(StringParser.of("PROBE_TIP "))
                    .or(StringParser.of("REAGENT_GAS ")).or(StringParser.of("RESOLUTION "))
                    .or(StringParser.of("RESOLUTION_SETTING ")).or(StringParser.of("RING_VOLTAGE "))
                    .or(StringParser.of("SAMPLE_DRIPPING ")).or(StringParser.of("SCANNING "))
                    .or(StringParser.of("SCANNING_CYCLE ")).or(StringParser.of("SCANNING_RANGE "))
                    .or(StringParser.of("SCAN_RANGE_M/Z ")).or(StringParser.of("SKIMMER_VOLTAGE "))
                    .or(StringParser.of("SOURCE_TEMPERATURE ")).or(StringParser.of("SPRAY_CURRENT "))
                    .or(StringParser.of("SPRAY_VOLTAGE ")).or(StringParser.of("TUBE_LENS_VOLTAGE ")));
    def("ac_mass_spectrometry", StringParser.of("AC$MASS_SPECTROMETRY").seq(ref("tagsep"))
            .seq(ref("ac_mass_spectrometry_subtag")).seq(Token.NEWLINE_PARSER.not()).pick(2)
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten()).map((List<String> value) -> {
                return Pair.of(value.get(0).trim(), value.get(1));
            }).seq(Token.NEWLINE_PARSER).pick(0).plus().map((List<Pair<String, String>> value) -> {
                //System.out.println(value);
                callback.AC_MASS_SPECTROMETRY(value);
                return value;
            }));

    // 2.4.6 AC$CHROMATOGRAPHY: subtag Description
    // Experimental Method and Conditions of Chromatographic Separation. Optional
    // AC$CHROMATOGRAPHY fields should be arranged by the alphabetical order of subtag names.
    // 2.4.6 Subtag: CAPILLARY_VOLTAGE
    // Voltage Applied to Capillary Electrophoresis or Voltage Applied to the Interface of LC-MS.
    // Example: AC$CHROMATOGRAPHY: CAPILLARY_VOLTAGE 4 kV
    // 2.4.6 Subtag: COLUMN_NAME
    // Commercial Name of Chromatography Column and Manufacture.
    // Example of LC: AC$CHROMATOGRAPHY: COLUMN_NAME Acquity UPLC BEH C18 2.1 by 50 mm (Waters, Milford, MA, USA) Example of CE: AC$CHROMATOGRAPHY: COLUMN_NAME Fused silica capillary id=50 um L=100 cm (HMT, Tsuruoka, Japan)
    // 2.4.6 Subtag: COLUMN_TEMPERATURE
    // Column Temperature.
    // Example: AC$CHROMATOGRAPHY: COLUMN_TEMPERATURE 40 C
    // 2.4.6 Subtag: FLOW_GRADIENT
    // Gradient of Elusion Solutions.
    // Example: AC$CHROMATOGRAPHY: FLOW_GRADIENT 0/100 at 0 min, 15/85 at 5 min, 21/79 at 20 min, 90/10 at 24 min, 95/5 at 26 min, 0/100, 30 min
    // 2.4.6 Subtag: FLOW_RATE
    // Flow Rate of Migration Phase.
    // Example: AC$CHROMATOGRAPHY: FLOW_RATE 0.25 ml/min
    // 2.4.6 Subtag: RETENTION_TIME
    // Retention Time on Chromatography.
    // Example: AC$CHROMATOGRAPHY: RETENTION_TIME 40.3 min
    // Cross-reference to mzOntology: Retention time [MS:1000016]
    // 2.4.6 Subtag: SOLVENT
    // Chemical Composition of Buffer Solution. Iterative
    // Example:
    // AC$CHROMATOGRAPHY: SOLVENT A acetonitrile-methanol-water (19:19:2) with 0.1% acetic acid
    // AC$CHROMATOGRAPHY: SOLVENT B 2-propanol with 0.1% acetic acid and 0.1% ammonium hydroxide (28%)
    // 2.4.6 Subtag: NAPS_RTI
    // N-alkylpyrinium-3-sulfonate based retention time index.
    // Reference: http://nparc.cisti-icist.nrc-cnrc.gc.ca/eng/view/object/?id=b4db3589-ae0b-497e-af03-264785d7922f
    // Example: AC$CHROMATOGRAPHY: NAPS_RTI 100   
    def("ac_chromatography_subtag",
            StringParser.of("ANALYTICAL_TIME ").or(StringParser.of("CAPILLARY_VOLTAGE "))
                    .or(StringParser.of("COLUMN_NAME ")).or(StringParser.of("COLUMN_PRESSURE "))
                    .or(StringParser.of("COLUMN_TEMPERATURE ")).or(StringParser.of("FLOW_GRADIENT "))
                    .or(StringParser.of("FLOW_RATE ")).or(StringParser.of("INJECTION_TEMPERATURE "))
                    .or(StringParser.of("INTERNAL_STANDARD ")).or(StringParser.of("INTERNAL_STANDARD_MT "))
                    .or(StringParser.of("NAPS_RTI ")).or(StringParser.of("MIGRATION_TIME "))
                    .or(StringParser.of("OVEN_TEMPERATURE ")).or(StringParser.of("PRECONDITIONING "))
                    .or(StringParser.of("RETENTION_INDEX ")).or(StringParser.of("RETENTION_TIME "))
                    .or(StringParser.of("RUNNING_BUFFER ")).or(StringParser.of("RUNNING_VOLTAGE "))
                    .or(StringParser.of("SAMPLE_INJECTION ")).or(StringParser.of("SAMPLING_CONE "))
                    .or(StringParser.of("SHEATH_LIQUID ")).or(StringParser.of("SOLVENT "))
                    .or(StringParser.of("TIME_PROGRAM ")).or(StringParser.of("TRANSFARLINE_TEMPERATURE "))
                    .or(StringParser.of("WASHING_BUFFER ")));
    def("ac_chromatography", StringParser.of("AC$CHROMATOGRAPHY").seq(ref("tagsep"))
            .seq(ref("ac_chromatography_subtag")).seq(Token.NEWLINE_PARSER.not()).pick(2)
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten()).map((List<String> value) -> {
                return Pair.of(value.get(0).trim(), value.get(1));
            }).seq(Token.NEWLINE_PARSER).pick(0).plus().map((List<Pair<String, String>> value) -> {
                //System.out.println(value);
                callback.AC_CHROMATOGRAPHY(value);
                return value;
            }));

    // 2.5.1 MS$FOCUSED_ION: subtag Description
    // Information of Precursor or Molecular Ion. Optional
    // MS$FOCUSED_ION fields should be arranged by the alphabetical order of subtag names.
    // 2.5.1 Subtag: BASE_PEAK
    // m/z of Base Peak.
    // Example: MS$FOCUSED_ION: BASE_PEAK 73
    // 2.5.1 Subtag: DERIVATIVE_FORM
    // Molecular Formula of Derivative for GC-MS.
    // Example
    // MS$FOCUSED_ION: DERIVATIVE_FORM C19H42O5Si4
    // MS$FOCUSED_ION: DERIVATIVE_FORM C{9+3*n}H{16+8*n}NO5Si{n}
    // 2.5.1 Subtag: DERIVATIVE_MASS
    // Exact Mass of Derivative for GC-MS.
    // Example: MS$FOCUSED_ION: DERIVATIVE_MASS 462.21093
    // 2.5.1 Subtag: DERIVATIVE_TYPE
    // Type of Derivative for GC-MS.
    // Example: MS$FOCUSED_ION: DERIVATIVE_TYPE 4 TMS
    // 2.5.1 Subtag: ION_TYPE
    // Type of Focused Ion.
    // Example: MS$FOCUSED_ION: ION_TYPE [M+H]+
    // Types currently used in MassBank are [M]+, [M]+*, [M+H]+, [2M+H]+, [M+Na]+, [M-H+Na]+, [2M+Na]+, [M+2Na-H]+, [(M+NH3)+H]+, [M+H-H2O]+, [M+H-C6H10O4]+, [M+H-C6H10O5]+, [M]-, [M-H]-, [M-2H]-, [M-2H+H2O]-, [M-H+OH]-, [2M-H]-, [M+HCOO-]-, [(M+CH3COOH)-H]-, [2M-H-CO2]- and [2M-H-C6H10O5]-.
    // 2.5.1 Subtag: PRECURSOR_M/Z
    // m/z of Precursor Ion in MSn spectrum.
    // Example: MS$FOCUSED_ION: PRECURSOR_M/Z 289.07123
    // Calculated exact mass is preferred to the measured accurate mass of the precursor ion. Cross-reference to mzOntology: precursor m/z [MS:1000504]
    // 2.5.1 Subtag: PRECURSOR_TYPE
    // Type of Precursor Ion in MSn.
    // Example: MS$FOCUSED_ION: PRECURSOR_TYPE [M-H]-
    // Types currently used in MassBank are [M]+, [M]+*, [M+H]+, [2M+H]+, [M+Na]+,
    // [M-H+Na]+, [2M+Na]+, [M+2Na-H]+, [(M+NH3)+H]+, [M+H-H2O]+, [M+H-C6H10O4]+,
    // [M+H-C6H10O5]+, [M]-, [M-H]-, [M-2H]-, [M-2H+H2O]-, [M-H+OH]-, [2M-H]-, [M+HCOO-]-,
    // [(M+CH3COOH)-H]-, [2M-H-CO2]- and [2M-H-C6H10O5]-. Cross-reference to mzOntology: Precursor type [MS: 1000792]

    def("precursor_type", StringParser.of("[M]+*").or(StringParser.of("[M]++")).or(StringParser.of("[M]+"))
            .or(StringParser.of("[M+H]+,[M-H2O+H]+")).or(StringParser.of("[M+H]+"))
            .or(StringParser.of("[M+2H]++")).or(StringParser.of("[2M+H]+")).or(StringParser.of("[M+Li]+*"))
            .or(StringParser.of("[M-H+Li]+*")).or(StringParser.of("[M+Na]+*")).or(StringParser.of("[M-H+Na]+*"))
            .or(StringParser.of("[M+Na]+")).or(StringParser.of("[M+K]+")).or(StringParser.of("[M+K]+"))
            .or(StringParser.of("[M-H2O+H]+,[M-2H2O+H]+")).or(StringParser.of("[M-H2O+H]+"))
            .or(StringParser.of("[M+15]+")).or(StringParser.of("[M-H+Na]+")).or(StringParser.of("[2M+Na]+"))
            .or(StringParser.of("[M+2Na-H]+")).or(StringParser.of("[(M+NH3)+H]+"))
            .or(StringParser.of("[M+NH4]+")).or(StringParser.of("[M+H-H2O]+"))
            .or(StringParser.of("[M-2H2O+H]+,[M-H2O+H]+")).or(StringParser.of("[M-2H2O+H]+"))
            .or(StringParser.of("[M+H-C6H10O4]+")).or(StringParser.of("[M+H-C6H10O5]+"))
            .or(StringParser.of("[M+H-C12H20O9]+")).or(StringParser.of("[M-H]+")).or(StringParser.of("[M-OH]+"))

            .or(StringParser.of("[M-3]+,[M-H2O+H]+"))

            .or(StringParser.of("[M]-")).or(StringParser.of("[M-H]-/[M-Ser]-")).or(StringParser.of("[M-H]-"))
            .or(StringParser.of("[M-2H]--")).or(StringParser.of("[M-2H]-")).or(StringParser.of("[M+K-2H]-"))
            .or(StringParser.of("[M-2H+H2O]-")).or(StringParser.of("[M-H+OH]-")).or(StringParser.of("[M-CH3]-"))
            .or(StringParser.of("[2M-H]-")).or(StringParser.of("[M+HCOO-]-")).or(StringParser.of("[M-C2H3O]-"))
            .or(StringParser.of("[M-C3H7O2]-")).or(StringParser.of("[M-H-C6H10O5]-"))
            .or(StringParser.of("[M-H-CO2]-")).or(StringParser.of("[(M+CH3COOH)-H]-"))
            .or(StringParser.of("[M+CH3COO]-/[M-CH3]-")).or(StringParser.of("[M+CH3COO]-"))
            .or(StringParser.of("[2M-H-CO2]-")).or(StringParser.of("[2M-H-C6H10O5]-"))
            .or(StringParser.of("[M-H-CO2-2HF]-")));
    def("ms_focused_ion_subtag",
            StringParser.of("BASE_PEAK ").or(StringParser.of("DERIVATIVE_FORM "))
                    .or(StringParser.of("DERIVATIVE_MASS ")).or(StringParser.of("DERIVATIVE_TYPE "))
                    .or(StringParser.of("FULL_SCAN_FRAGMENT_ION_PEAK ")).or(StringParser.of("PRECURSOR_M/Z ")));

    def("ms_focused_ion", StringParser.of("MS$FOCUSED_ION").seq(ref("tagsep")).seq(StringParser.of("ION_TYPE "))
            .pick(2).seq(ref("precursor_type")).map((List<String> value) -> {
                return Pair.of(value.get(0).trim(), value.get(1));
            }).seq(Token.NEWLINE_PARSER).pick(0)
            .or(StringParser.of("MS$FOCUSED_ION").seq(ref("tagsep")).seq(StringParser.of("PRECURSOR_TYPE "))
                    .pick(2).seq(ref("precursor_type")).map((List<String> value) -> {
                        return Pair.of(value.get(0).trim(), value.get(1));
                    }).seq(Token.NEWLINE_PARSER).pick(0))
            .or(StringParser.of("MS$FOCUSED_ION").seq(ref("tagsep")).seq(ref("ms_focused_ion_subtag"))
                    .seq(Token.NEWLINE_PARSER.not()).pick(2)
                    .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten())
                    .map((List<String> value) -> {
                        return Pair.of(value.get(0).trim(), value.get(1));
                    }).seq(Token.NEWLINE_PARSER).pick(0))
            .plus().map((List<Pair<String, String>> value) -> {
                //System.out.println(value);
                callback.MS_FOCUSED_ION(value);
                return value;
            }));

    // 2.5.3 MS$DATA_PROCESSING: subtag
    // Data Processing Method of Peak Detection. Optional
    // MS$DATA_PROCESSING fields should be arranged by the alphabetical order of subtag names. Cross-reference to mzOntology: Data processing [MS:1000543]
    // 2.5.3 Subtag: FIND_PEAK
    // Peak Detection.
    // Example: MS$DATA_PROCESSING: FIND_PEAK convexity search; threshold = 9.1
    // 2.5.3 Subtag: WHOLE
    // Whole Process in Single Method / Software.
    // Example: MS$DATA_PROCESSING: WHOLE Analyst 1.4.2
    def("ms_data_processing_subtag",
            StringParser.of("CHARGE_DECONVOLUTION ").or(StringParser.of("DEPROFILE "))
                    .or(StringParser.of("FIND_PEAK ")).or(StringParser.of("IGNORE "))
                    .or(StringParser.of("INTENSITY CUTOFF ")).or(StringParser.of("REANALYZE "))
                    .or(StringParser.of("RECALIBRATE ")).or(StringParser.of("RELATIVE_M/Z "))
                    .or(StringParser.of("REMOVE_PEAK ")).or(StringParser.of("WHOLE ")));
    def("ms_data_processing", StringParser.of("MS$DATA_PROCESSING").seq(ref("tagsep"))
            .seq(ref("ms_data_processing_subtag")).seq(Token.NEWLINE_PARSER.not()).pick(2)
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten()).map((List<String> value) -> {
                return Pair.of(value.get(0).trim(), value.get(1));
            }).seq(Token.NEWLINE_PARSER).pick(0).plus()

            .map((List<Pair<String, String>> value) -> {
                //System.out.println(value);
                callback.MS_DATA_PROCESSING(value);
                return value;
            }));

    // 2.6.1 PK$SPLASH
    // Hashed Identifier of Mass Spectra. Mandatory and Single Line Information
    // Example: PK$SPLASH: splash10-z200000000-87bb3c76b8e5f33dd07f
    def("pk_splash", StringParser.of("PK$SPLASH").seq(ref("tagsep"))
            .seq(CharacterParser.any().plusLazy(Token.NEWLINE_PARSER).flatten().map((String value) -> {
                callback.PK_SPLASH(value);
                return value;
            })).seq(Token.NEWLINE_PARSER)
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );

    // 2.6.2 PK$ANNOTATION
    // Chemical Annotation of Peaks with Molecular Formula. Optional and Multiple Line Information
    // TODO call callback function
    def("pk_annotation",
            StringParser.of("PK$ANNOTATION").seq(ref("tagsep"))
                    .seq(CharacterParser.word().or(CharacterParser.anyOf("-+,()[]{}\\/.:$^'`_*?<>=")).plus()
                            .flatten().trim(CharacterParser.of(' ')).plus().map((List<String> value) -> {
                                //               System.out.println(value);
                                callback.PK_ANNOTATION_HEADER(value);
                                return value;
                            }).seq(Token.NEWLINE_PARSER))
                    .seq(StringParser.of("  ")
                            //            .map((String value) -> {
                            //               //System.out.println(value);
                            //               callback.ADD_PK_ANNOTATION_LINE();
                            //               return value;                  
                            //            })
                            .seq(CharacterParser.word().or(CharacterParser.anyOf("-+,()[]{}\\/.:$^'`_*?<>="))
                                    .plus().flatten().trim(CharacterParser.of(' ')).plus()
                                    .map((List<String> value) -> {
                                        //                  System.out.println(value);
                                        callback.PK_ANNOTATION_ADD_LINE(value);
                                        return value;
                                    }).seq(Token.NEWLINE_PARSER)
                                    // call a Continuation Parser to validate the count of PK$ANNOTATION items per line
                                    .callCC((Function<Context, Result> continuation, Context context) -> {
                                        Result r = continuation.apply(context);
                                        if (r.isSuccess()) {
                                            List<String> pk_annotation_header = callback.PK_ANNOTATION_HEADER();
                                            List<List<String>> pk_annotation = callback.PK_ANNOTATION();
                                            if (pk_annotation_header.size() != pk_annotation
                                                    .get(pk_annotation.size() - 1).size()) {
                                                StringBuilder sb = new StringBuilder();
                                                sb.append(
                                                        "Incorrect number of fields per PK$ANNOTATION line. ");
                                                sb.append(pk_annotation_header.size() + " fields expected, but "
                                                        + pk_annotation.get(pk_annotation.size() - 1).size()
                                                        + " fields found.\n");
                                                sb.append("Defined by:\n");
                                                sb.append("PK$ANNOTATION:");
                                                for (String annotation_header_item : callback
                                                        .PK_ANNOTATION_HEADER())
                                                    sb.append(" " + annotation_header_item);
                                                System.out.println(sb.toString());
                                                return context.failure(sb.toString());
                                            }
                                        }
                                        return r;
                                    }))
                            .plus()));

    def("pk_num_peak", StringParser.of("PK$NUM_PEAK").seq(ref("tagsep"))
            .seq(digit().plus().flatten().map((String value) -> {
                Integer i = Integer.parseUnsignedInt(value);
                callback.PK_NUM_PEAK(i);
                return value;
            })).seq(Token.NEWLINE_PARSER));

    def("pk_peak",
            StringParser.of("PK$PEAK").seq(ref("tagsep")).seq(StringParser.of("m/z int. rel.int."))
                    .seq(Token.NEWLINE_PARSER).seq(StringParser.of("  ").seq(ref("number").trim()).pick(1)
                            .seq(ref("number").trim()).seq(ref("number")).map((List<String> value) -> {
                                //               System.out.println(value);
                                List<Double> list = new ArrayList<Double>();
                                for (String val : value)
                                    list.add(Double.parseDouble(val));
                                callback.PK_PEAK_ADD_LINE(list);
                                return value;
                            }).seq(Token.NEWLINE_PARSER).plus())
                    // call a Continuation Parser to validate the number of peaks in the peaklist
                    .callCC((Function<Context, Result> continuation, Context context) -> {
                        Result r = continuation.apply(context);
                        if (r.isSuccess()) {
                            Integer num_peak = callback.PK_NUM_PEAK();
                            List<List<Double>> pk_peak = callback.PK_PEAK();
                            if (pk_peak.size() != num_peak) {
                                StringBuilder sb = new StringBuilder();
                                sb.append("Incorrect number of peaks in peaklist. ");
                                sb.append(num_peak + " peaks are declared in PK$NUM_PEAK line, but "
                                        + pk_peak.size() + " peaks are found.\n");
                                return context.failure(sb.toString());
                            }

                            List<Ion> ions = new ArrayList<Ion>();
                            for (List<Double> peak_line : pk_peak) {
                                ions.add(new Ion(peak_line.get(0), peak_line.get(1)));
                            }
                            Splash splashFactory = SplashFactory.create();
                            Spectrum spectrum = new SpectrumImpl(ions, SpectraType.MS);
                            String splash_from_peaks = splashFactory.splashIt(spectrum);
                            String splash_from_record = callback.PK_SPLASH();
                            if (!splash_from_peaks.equals(splash_from_record)) {
                                StringBuilder sb = new StringBuilder();
                                sb.append(
                                        "SPLASH from record file does not match SPLASH calculated from peaklist. ");
                                sb.append(splash_from_record + " defined in record file, but "
                                        + splash_from_peaks + " calculated from peaks.\n");
                                return context.failure(sb.toString());
                            }
                        }
                        return r;
                    })
    //         .map((List<?> value) -> {
    //            System.out.println(value);
    //            return value;                  
    //         })
    );
}

From source file:org.vmtest.currency.OpenExchangeRestClientTest.java

@Test
public void shouldReturnHistoricalCurrencyRates() {

    CurrencyRates result = service.getExchangeRates(source, currencies, LocalDate.of(2015, 10, 19));
    assertEquals("USD", result.getSource());
    assertEquals(8, result.getRates().size());
}

From source file:org.vaadin.peholmst.samples.dddwebinar.TestDataGenerator.java

private static LocalDate randomDate(int yearsBack) {
    LocalDate now = LocalDate.now();
    return LocalDate.of(now.getYear() - RND.nextInt(yearsBack), RND.nextInt(12) + 1, RND.nextInt(28) + 1);
}

From source file:cz.muni.fi.pv168.project.hotelmanager.TestReservationManagerImpl.java

@Test
public void testCreateReservationWithWrongValues() {

    LocalDate checkin = LocalDate.of(2016, 8, 7);
    LocalDate checkout = LocalDate.of(2016, 8, 11);
    LocalDate reservationdate = LocalDate.now(prepareClockMock(now));
    Reservation reservation;/*w w  w  .j a  v  a  2s  .  c om*/

    reservation = setReservation(-5, 1, checkin, checkout, reservationdate);
    try {
        reservationManager.createReservation(reservation);
        fail("wrong room id(negative value)");
    } catch (IllegalArgumentException ex) {
        //OK
    }

    reservation = setReservation(1, -1, checkin, checkout, reservationdate);
    try {
        reservationManager.createReservation(reservation);
        fail("wrong guest id (negative value)");
    } catch (IllegalArgumentException ex) {
        //OK
    }

    reservation = setReservation(1, 1, checkin.plusMonths(3), checkout, reservationdate);
    try {
        reservationManager.createReservation(reservation);
        fail("checkin after checkout");
    } catch (IllegalArgumentException ex) {
        //OK
    }

    reservation = setReservation(1, 1, checkin, checkout, reservationdate.plusYears(1));
    try {
        reservationManager.createReservation(reservation);
        fail("reservation date after checkin");
    } catch (IllegalArgumentException ex) {
        //OK
    }

    reservation = setReservation(1, 1, checkin, null, reservationdate);
    try {
        reservationManager.createReservation(reservation);
        fail("checkout is null");
    } catch (IllegalArgumentException ex) {
        //OK
    }

    reservation = setReservation(1, 1, null, checkout, reservationdate);
    try {
        reservationManager.createReservation(reservation);
        fail("checkin is null");
    } catch (IllegalArgumentException ex) {
        //OK
    }
}