text: // Filesystem utilities using the synchronous API in a worker thread
  var filesystem = requestFileSystemSync(PERSISTENT, 10*1024*1024);
  
  function readTextFile(name) {
      // Get a File from a FileEntry from the root DirectoryEntry
      var file = filesystem.root.getFile(name).file();
      // Use the synchronous FileReader API to read it 
      return new FileReaderSync().readAsText(file);
  }
  
  function appendToFile(name, contents) {
      // Get a FileWriter from a FileEntry from the root DirectoryEntry
      var writer = filesystem.root.getFile(name, {create:true}).createWriter();
      writer.seek(writer.length);  // Start at the end of the file
      var bb = new BlobBuilder()   // Build the file contents into a Blob
      bb.append(contents);
      writer.write(bb.getBlob());   // Now write the blob to the file
  }
  
  function deleteFile(name) {
      filesystem.root.getFile(name).remove();
  }
  
  function makeDirectory(name) {
      filesystem.root.getDirectory(name, { create: true, exclusive:true });
  }
  
  function listFiles(path) {
      var dir = filesystem.root;
      if (path) dir = dir.getDirectory(path);
      
      var lister = dir.createReader();
      var list = [];
      do {
          var entries = lister.readEntries();
          for(var i = 0; i < entries.length; i++) {
              var name = entries[i].name;
              if (entries[i].isDirectory) name += "/";
              list.push(name);
          }
      } while(entries.length > 0);
  
      return list;
  }
  
  // Allow the main thread to use these utilities by sending a message
  onmessage = function(e) {
      // We expect the message to be an object like this:
      // { function: "appendToFile", args: ["test", "testing, testing"]}
      // We invoke the specified function with the specified args and
      // post the message back 
      var f = self[e.data.function];
      var result = f.apply(null, e.data.args);
      postMessage(result);
  };
  