input: Write a function called FileSystem with methods for saving, deleting, and finding task data. The taskDir parameter specifies the directory where task data should be stored. If the task data dictionary does not include an 'id' key, one will be generated and added to the dictionary. When saving, the task data will be stored in a file within a subdirectory of taskDir named after the task ID. The function should include methods for deleting a task by ID, finding task data by ID, finding task data by multiple IDs, retrieving all task data, and getting task data for a specific ID without raising an error if the data is not found.
  assert FileSystem({'taskDir': '~/jsub/'}).save_task({'name': 'Task1', 'status': 'pending'})['id'] is not None
  assert len(FileSystem({'taskDir': '~/jsub/'}).find_by_ids([1])) == 1
  assert FileSystem({'taskDir': '~/jsub/'}).delete_task(1) == None
  assert len(FileSystem({'taskDir': '~/jsub/'}).find_by_ids([1])) == 0
  assert FileSystem({'taskDir': '~/jsub/'}).all_task_data() == []
  assert FileSystem({'taskDir': '~/jsub/'}).task_data(999) == None
output: class FileSystem:
      def __init__(self, config):
          self.taskDir = config['taskDir']
  
      def save_task(self, task_data):
          if 'id' not in task_data:
              task_data['id'] = self._generate_id()
          task_id = task_data['id']
          task_dir = os.path.join(self.taskDir, str(task_id))
          os.makedirs(task_dir, exist_ok=True)
          with open(os.path.join(task_dir, 'task_data.json'), 'w') as f:
              json.dump(task_data, f)
          return task_data
  
      def delete_task(self, task_id):
          task_dir = os.path.join(self.taskDir, str(task_id))
          if os.path.exists(task_dir):
              shutil.rmtree(task_dir)
  
      def find_by_id(self, task_id):
          task_dir = os.path.join(self.taskDir, str(task_id))
          task_file = os.path.join(task_dir, 'task_data.json')
          if os.path.exists(task_file):
              with open(task_file, 'r') as f:
                  return json.load(f)
          return None
  
      def find_by_ids(self, task_ids):
          return [self.find_by_id(task_id) for task_id in task_ids if self.find_by_id(task_id) is not None]
  
      def all_task_data(self):
          task_ids = [d for d in os.listdir(self.taskDir) if os.path.isdir(os.path.join(self.taskDir, d))]
          return self.find_by_ids(task_ids)
  
      def task_data(self, task_id):
          return self.find_by_id(task_id)
  
      def _generate_id(self):
          return len([d for d in os.listdir(self.taskDir) if os.path.isdir(os.path.join(self.taskDir, d))]) + 1