// Path: src/main/java/com/qoomon/banking/swift/message/exception/SwiftMessageParseException.java
// public class SwiftMessageParseException extends Exception {
// 
//     private final int lineNumber;
// 
//     public SwiftMessageParseException(String message, int lineNumber) {
//         super(message + " at line number " + lineNumber);
//         this.lineNumber = lineNumber;
//     }
// 
//     public SwiftMessageParseException(String message, int lineNumber, Throwable cause) {
//         super(message + " at line number " + lineNumber, cause);
//         this.lineNumber = lineNumber;
//     }
// 
//     public SwiftMessageParseException(int lineNumber, Throwable cause) {
//         super("at line number " + lineNumber, cause);
//         this.lineNumber = lineNumber;
//     }
// 
//     public SwiftMessageParseException(BlockParseException e) {
//         super(e);
//         lineNumber = 0;
//     }
// 
//     public int getLineNumber() {
//         return lineNumber;
//     }
// }


import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.qoomon.banking.swift.message.block.*;
import com.qoomon.banking.swift.message.exception.SwiftMessageParseException;
import java.io.Reader;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
                        nextValidBlockIdSet = ImmutableSet.of(UserTrailerBlock.BLOCK_ID_5, SystemTrailerBlock.BLOCK_ID_S);
                        break;
                    }
                    case UserTrailerBlock.BLOCK_ID_5: {
                        messageBuilderUserTrailerBlock = UserTrailerBlock.of(currentBlock);
                        nextValidBlockIdSet = ImmutableSet.of(SystemTrailerBlock.BLOCK_ID_S);
                        break;
                    }
                    case SystemTrailerBlock.BLOCK_ID_S: {
                        messageBuilderSystemTrailerBlock = SystemTrailerBlock.of(currentBlock);
                        nextValidBlockIdSet = ImmutableSet.of();
                        break;
                    }
                    default:
                        throw new SwiftMessageParseException("unexpected block id '" + currentBlock.getId() + "'", blockReader.getLineNumber());
                }

                // finish message
                if (nextBlock == null || MESSAGE_START_BLOCK_ID_SET.contains(nextBlock.getId())) {
                    message = new SwiftMessage(
                            messageBuilderBasicHeaderBlock,
                            messageBuilderApplicationHeaderBlock,
                            messageBuilderUserHeaderBlock,
                            messageBuilderTextBlock,
                            messageBuilderUserTrailerBlock,
                            messageBuilderSystemTrailerBlock);
                }
            }

            return message;
// Path: src/main/java/com/qoomon/banking/swift/message/exception/SwiftMessageParseException.java
// public class SwiftMessageParseException extends Exception {
// 
//     private final int lineNumber;
// 
//     public SwiftMessageParseException(String message, int lineNumber) {
//         super(message + " at line number " + lineNumber);
//         this.lineNumber = lineNumber;
//     }
// 
//     public SwiftMessageParseException(String message, int lineNumber, Throwable cause) {
//         super(message + " at line number " + lineNumber, cause);
//         this.lineNumber = lineNumber;
//     }
// 
//     public SwiftMessageParseException(int lineNumber, Throwable cause) {
//         super("at line number " + lineNumber, cause);
//         this.lineNumber = lineNumber;
//     }
// 
//     public SwiftMessageParseException(BlockParseException e) {
//         super(e);
//         lineNumber = 0;
//     }
// 
//     public int getLineNumber() {
//         return lineNumber;
//     }
// }


// Path: src/main/java/com/qoomon/banking/swift/message/SwiftMessageReader.java
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.qoomon.banking.swift.message.block.*;
import com.qoomon.banking.swift.message.exception.SwiftMessageParseException;
import java.io.Reader;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

                        nextValidBlockIdSet = ImmutableSet.of(UserTrailerBlock.BLOCK_ID_5, SystemTrailerBlock.BLOCK_ID_S);
                        break;
                    }
                    case UserTrailerBlock.BLOCK_ID_5: {
                        messageBuilderUserTrailerBlock = UserTrailerBlock.of(currentBlock);
                        nextValidBlockIdSet = ImmutableSet.of(SystemTrailerBlock.BLOCK_ID_S);
                        break;
                    }
                    case SystemTrailerBlock.BLOCK_ID_S: {
                        messageBuilderSystemTrailerBlock = SystemTrailerBlock.of(currentBlock);
                        nextValidBlockIdSet = ImmutableSet.of();
                        break;
                    }
                    default:
                        throw new SwiftMessageParseException("unexpected block id '" + currentBlock.getId() + "'", blockReader.getLineNumber());
                }

                // finish message
                if (nextBlock == null || MESSAGE_START_BLOCK_ID_SET.contains(nextBlock.getId())) {
                    message = new SwiftMessage(
                            messageBuilderBasicHeaderBlock,
                            messageBuilderApplicationHeaderBlock,
                            messageBuilderUserHeaderBlock,
                            messageBuilderTextBlock,
                            messageBuilderUserTrailerBlock,
                            messageBuilderSystemTrailerBlock);
                }
            }

            return message;
        } catch (SwiftMessageParseException e) {