ExternalSystemEvent (@NotNull String line, int version) { int payloadStartIndex = version == 0 ? 2 : 3; String[] parts = line.split(" "); int length = parts.length; if (length < payloadStartIndex) { return null; } ExternalSystemEventType type = ExternalSystemEventType.parse(parts[1]); if (type == null) { return null; } long timestamp = parseLong(parts[0]); String recorderId = version == 0 ? "FUS" : parts[2]; if (type == ExternalSystemEventType.FINISHED) { String error = length > payloadStartIndex ? parts[payloadStartIndex].trim() : null; return new ExternalUploadFinishedEvent(timestamp, error, recorderId); } else if (type == ExternalSystemEventType.SEND && length > payloadStartIndex + 2) { int succeed = parseInt(parts[payloadStartIndex]); int failed = parseInt(parts[payloadStartIndex + 1]); int total = parseInt(parts[payloadStartIndex + 2]); List<String> sentFiles = length > payloadStartIndex + 3 ? parseSentFiles(parts[payloadStartIndex + 3]) : Collections.emptyList(); List<Integer> errors = length > payloadStartIndex + 4 ? parseErrors(parts[payloadStartIndex + 4]) : Collections.emptyList(); return new ExternalUploadSendEvent(timestamp, succeed, failed, total, sentFiles, errors, recorderId); } else if (type == ExternalSystemEventType.STARTED && length == payloadStartIndex) { return new ExternalUploadStartedEvent(timestamp, recorderId); } else if (type == ExternalSystemEventType.ERROR && length == payloadStartIndex + 2) { String event = parts[payloadStartIndex].trim(); String errorClass = parts[payloadStartIndex + 1].trim(); return new ExternalSystemErrorEvent(timestamp, event, errorClass, recorderId); } return null; }