<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add_real_directory(self, source_path, read_only=True, lazy_read=True, target_path=None):
 """Create a fake directory corresponding to the real directory at the specified path. Add entries in the fake directory corresponding to the entries in the real directory. Args: source_path: The path to the existing directory. read_only: If set, all files under the directory are treated as read-only, e.g. a write access raises an exception; otherwise, writing to the files changes the fake files only as usually. lazy_read: If set (default), directory contents are only read when accessed, and only until the needed subdirectory level. .. note:: This means that the file system size is only updated at the time the directory contents are read; set this to `False` only if you are dependent on accurate file system size in your test target_path: If given, the target directory, otherwise, the target directory is the same as `source_path`. Returns: the newly created FakeDirectory object. Raises: OSError: if the directory does not exist in the real file system. IOError: if the directory already exists in the fake file system. """

        source_path = self._path_without_trailing_separators(source_path)
        if not os.path.exists(source_path):
            self.raise_io_error(errno.ENOENT, source_path)
        target_path = target_path or source_path
        if lazy_read:
            parent_path = os.path.split(target_path)[0]
            if self.exists(parent_path):
                parent_dir = self.get_object(parent_path)
            else:
                parent_dir = self.create_dir(parent_path)
            new_dir = FakeDirectoryFromRealDirectory(
                source_path, self, read_only, target_path)
            parent_dir.add_entry(new_dir)
            self._last_ino += 1
            new_dir.st_ino = self._last_ino
        else:
            new_dir = self.create_dir(target_path)
            for base, _, files in os.walk(source_path):
                new_base = os.path.join(new_dir.path,
                                        os.path.relpath(base, source_path))
                for fileEntry in files:
                    self.add_real_file(os.path.join(base, fileEntry),
                                       read_only,
                                       os.path.join(new_base, fileEntry))
        return new_dir