CSCI-20 Assignment #4, threaded trees, 250 points, due 5/19/16 Your assignment is to model a UNIX-like file system using a threaded tree. This UNIX-like file system has two types of nodes, directories and files. Directories contain other directories or files, represented by the children of the directory node. Files do not contain other files, so files are always leaf nodes. The file system begins with a single directory node, the root, which has the name "/" (slash). The root is its own parent, so its thread points to itself. All other nodes in the system will be children, grandchildren, etc. of the root node. Until changed by a chdir command, the current working directory (cwd) will be the root. Your program will support the following commands: mkdir name – make a new directory in the cwd with this name, if not a duplicate rmdir name – remove the directory with this name, and all its descendants, if legal chdir name – change cwd to the one indicated by name, if legal support ".." for parent, "." for self, and "/" for root or an absolute or relative path ls – list all files and directories in the cwd lsr – recursively list all file in this and all subdirectories mkfile name – create a new file with this name in the cwd, if legal rmfile name – delete the file with this name in the cwd, if legal pwd – print the full path from the root to the cwd Q – quit Just represent files by their name and type, so ordinary files (non-directories) will contain no data. Your program must take its input and output file names from the command line, and validate all initialization before running. You will process input until either end-of-file or you encounter a 'Q' command. After encountering the 'Q', change directory to the root and execute a pwd command and an lsr command. Your output is an audit of everything the program does. Thus, you should be able to completely recreate the input file from the output audit. Your output will also show the effect of each command in the input file. On any command failure, log a message to output that fully explains the failure. You must check for errors in the input, for example: you cannot mkdir or mkfile a directory or file if the name exists already in the cwd you cannot rmdir or rmfile a directory or file if the name doesn't exist in the cwd you cannot chdir to a file you cannot rmfile a directory or a non-existent file You may (will) find other problems that you also need to check for. This program needs to be robust. Keep the file and directory names in each directory in ascending lexicographic order. If you wish, you may keep directories and files in separate groups in the list of children, directories first and then files, rather than intermingled. lsr should do a recursive call to itself whenever it encounters a directory in its search. You should indent the output from each level by three spaces for each level of recursion (no indenting spaces the original call). Hint: make lsr a wrapper around a helper that takes the level of nesting, starting at 0. pwd prints the entire path from root to the cwd with slashes before (for the root) between and after the names, e.g., if usr, bin and sys are nested directories in the root, and you encounter pwd while sys is the cwd, you will print this: /usr/bin/sys/ chdir must move you to a legal directory, or fail completely and leave you in the same directory. rmdir must correctly remove all files and subdirectories along with their contents. I wrote this in about 580 lines of code, in about six hours. I expect it to take you more, both time and line of code. Start early and design fully before you write code or you'll never finish this! Do a test with my test file (fileTest.txt), which is on my Web site, and some with your own data files. Include at least two of your own test files, at least one of which creates at least a four-level file system and 25 files spread throughout the file system (all directories have at least one file) and which does an lsr command from the root directory before quitting. Use reasonable names for the files so I can tell which data file goes with which output. Again, a full design, before you write any code, is going to be critical for this. If you don't solve this first, then code afterwards, you will not be able to make this work. The interface to a data structure is keys and objects. The interface from the client to the class that implements the file system is commands and argument strings. This says you need to separate the data structure from the command interface. You may do this with a nested class for the data structure, or with an internal data structure controlled by the code to the file system class. You may do this in a couple of different ways, but the client needs to be able to have a command interface, not a key/object interface to the file system.