private Selector nextRecord() throws BeanReaderException {
        Selector parser = null;
        
        // clear the current record name
        recordName = null;
        
        do {
            // read the next record
            context.nextRecord();
    
            // validate all record nodes are satisfied when the end of the file is reached
            if (context.isEOF()) {
                try {
                    // calling close will determine if all min occurs have been met
                    Selector unsatisfied = layout.close(context);
                    if (unsatisfied != null) {
                        if (unsatisfied.isRecordGroup()) {
                            throw context.newUnsatisfiedGroupException(unsatisfied.getName());
                        }
                        else {
                            throw context.newUnsatisfiedRecordException(unsatisfied.getName());
                        }
                    }
                    return null;
                }
                finally {
                    layout = null;
                    lineNumber = -1;
                }
            }
            
            // update the last line number read
            lineNumber = context.getLineNumber();
            
            try {
                parser = layout.matchNext(context);
            }
            catch (UnexpectedRecordException ex) {
                // when thrown, 'parser' is null and the error is handled below
            }
            
            if (parser == null && ignoreUnidentifiedRecords) {
                context.recordSkipped();
            }
            else {
                break;
            }
        }
        while (true);

        if (parser == null) {
            parser = layout.matchAny(context);

            if (parser != null) {
                throw context.recordUnexpectedException(parser.getName());
            }
            else {
                throw context.recordUnidentifiedException();
            }
        }
        
        recordName = parser.getName();
        return parser;
    }