println(" cd <dirID>|'..'   Changes directory");
println(" ls                List contents of current directory"); println(" cd <dirName>      Changes directory by name"); println(" cdn <dirID>       Changes directory by ID"); println(" info <fileID>     Gets extensive information about the file.");
    public static void operationBrowse(Operation op, LowLevelFile hfsFile, long fsOffset, long fsLength) {	HFSFileSystemView fsView = new HFSFileSystemView(hfsFile, fsOffset);	HFSPlusCatalogLeafRecord rootRecord = fsView.getRoot();	HFSPlusCatalogLeafRecord currentDir = rootRecord;	LinkedList<String> pathStack = new LinkedList<String>();	pathStack.addLast("");	BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));		while(true) {	    StringBuilder currentPath = new StringBuilder();	    for(String pathComponent : pathStack) {		currentPath.append(pathComponent);		currentPath.append("/");	    }	    println("Listing files in \"" + currentPath.toString() + "\":");	    	    HFSPlusCatalogLeafRecord[] recordsInDir = fsView.listRecords(currentDir);	    for(HFSPlusCatalogLeafRecord rec : recordsInDir) {		HFSPlusCatalogLeafRecordData recData = rec.getData();		if(recData.getRecordType() == HFSPlusCatalogLeafRecordData.RECORD_TYPE_FILE &&		   recData instanceof HFSPlusCatalogFile) {		    HFSPlusCatalogFile catFile = (HFSPlusCatalogFile)recData;		    println("  [" + catFile.getFileID() + "] \"" + rec.getKey().getNodeName() + "\" (" + catFile.getDataFork().getLogicalSize() + " B)");		}		else if(recData.getRecordType() == HFSPlusCatalogLeafRecordData.RECORD_TYPE_FOLDER &&			recData instanceof HFSPlusCatalogFolder) {		    HFSPlusCatalogFolder catFolder = (HFSPlusCatalogFolder)recData;		    println("  [" + catFolder.getFolderID() + "] \"" + rec.getKey().getNodeName() + "/\"");		}	    }	    	    long nextID = -1;	    while(nextID < 0) {		print("Command[?]: ");				String input = null;		try {		    input = stdIn.readLine().trim();		} catch(IOException ioe) {		    ioe.printStackTrace();		    return;		}		if(input.equalsIgnoreCase("?")) {		    println("Available commands:");		    println(" cd <dirID>|'..'   Changes directory");		    println(" extract <fileID>  Extracts <fileID> to current directory");		    println(" q                 Quits program");		}		else if(input.equals("q"))		    return;		else if(input.startsWith("extract")) {		    input = input.substring("extract".length()).trim();		    try {						nextID = Long.parseLong(input);						HFSPlusCatalogLeafRecord selectedFileRecord = null;			HFSPlusCatalogFile selectedFile = null;			for(HFSPlusCatalogLeafRecord rec : recordsInDir) {			    HFSPlusCatalogLeafRecordData recData = rec.getData();			    if(recData.getRecordType() == HFSPlusCatalogLeafRecordData.RECORD_TYPE_FILE &&			       recData instanceof HFSPlusCatalogFile) {				selectedFileRecord = rec;				selectedFile = (HFSPlusCatalogFile)recData;			    }			}			if(selectedFileRecord == null) {			    println("ID not present in dir.");			    nextID = -1;			}			else {			    selectedFileRecord.print(System.out, "");			    String dataForkFilename = selectedFileRecord.getKey().getNodeName().toString();			    FileOutputStream dataOut = new FileOutputStream(dataForkFilename);			    print("Extracting data fork to file \"" + dataForkFilename + "\"...");			    try {				long bytesExtracted = fsView.extractDataForkToStream(selectedFile, dataOut);				println("extracted " + bytesExtracted + " bytes.");				dataOut.close();			    } catch(IOException ioe) {				ioe.printStackTrace();				try { dataOut.close(); } catch(IOException ioe2) {}				continue; // or rather... don't continue (: mwahaha			    }			    			    String resourceForkFilename = dataForkFilename + ".resourcefork";			    FileOutputStream resourceOut = new FileOutputStream(resourceForkFilename);			    print("Extracting resource fork to file \"" + resourceForkFilename + "\"...");			    try {				long bytesExtracted = fsView.extractResourceForkToStream(selectedFile, resourceOut);				println("extracted " + bytesExtracted + " bytes.");				resourceOut.close();			    } catch(IOException ioe) {				ioe.printStackTrace();				try { dataOut.close(); } catch(IOException ioe2) {}			    }			}					    } catch(FileNotFoundException fnfe) {			fnfe.printStackTrace();		    } catch(NumberFormatException nfe) {			nextID = -1;			println("Invalid input!");		    }		}		else if(input.startsWith("cd")) {		    input = input.substring(2).trim();		    if(input.equals("..")) {			println("Not yet implemented.");			// Implement this.		    }		    else {			try {			    nextID = Long.parseLong(input);			    HFSPlusCatalogLeafRecord nextDir = null;			    for(HFSPlusCatalogLeafRecord rec : recordsInDir) {				HFSPlusCatalogLeafRecordData recData = rec.getData();				if(recData.getRecordType() == HFSPlusCatalogLeafRecordData.RECORD_TYPE_FOLDER &&				   recData instanceof HFSPlusCatalogFolder) {				    HFSPlusCatalogFolder catFolder = (HFSPlusCatalogFolder)recData;				    if(Util2.unsign(catFolder.getFolderID().toInt()) == nextID) {					nextDir = rec;					break;				    }				}			    }			    if(nextDir == null) {				println("ID not present in dir.");				nextID = -1;			    }			    else {				pathStack.addLast(nextDir.getKey().getNodeName().toString());				currentDir = nextDir;			    }			} catch(Exception e) {			    nextID = -1;			    println("Invalid input!");			}		    }		}	    }	    println();	}    }