class ProjectInformationImpl implements ProjectInformation {

    //Data
    private final Project project;
    //Event
    private final transient List<PropertyChangeListener> listeners;
    private String name;
    private Status status = Status.CLOSED;
    private File file;

    public ProjectInformationImpl(Project project, String name) {
        this.project = project;
        this.name = name;
        listeners = new ArrayList<>();
    }

    public void open() {
        Status oldStatus = status;
        status = Status.OPEN;
        fireChangeEvent(ProjectInformation.EVENT_OPEN, oldStatus, status);
    }

    public void close() {<FILL_FUNCTION_BODY>}

    @Override
    public Project getProject() {
        return project;
    }

    //PROPERTIES
    @Override
    public boolean isOpen() {
        return status == Status.OPEN;
    }

    @Override
    public boolean isClosed() {
        return status == Status.CLOSED;
    }

    @Override
    public boolean isInvalid() {
        return status == Status.INVALID;
    }

    @Override
    public boolean hasFile() {
        return file != null;
    }

    @Override
    public String getFileName() {
        if (file == null) {
            return "";
        } else {
            return file.getName();
        }
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("Project name cannot be null or empty");
        }
        String oldName = this.name;
        this.name = name;
        fireChangeEvent(ProjectInformation.EVENT_RENAME, oldName, name);
    }

    @Override
    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        File oldFile = this.file;
        this.file = file;
        fireChangeEvent(ProjectInformation.EVENT_SET_FILE, oldFile, file);
    }

    //EVENTS
    @Override
    public void addChangeListener(PropertyChangeListener listener) {
        listeners.add(listener);
    }

    @Override
    public void removeChangeListener(PropertyChangeListener listener) {
        listeners.remove(listener);
    }

    public void fireChangeEvent(String eventName, Object oldValue, Object newValue) {
        if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null)
            || (oldValue != null && !oldValue.equals(newValue))) {
            PropertyChangeEvent event = new PropertyChangeEvent(this, eventName, oldValue, newValue);
            for (PropertyChangeListener listener : listeners) {
                listener.propertyChange(event);
            }
        }
    }

    public enum Status {

        NEW, OPEN, CLOSED, INVALID
    }
}

        Status oldStatus = status;
        status = Status.CLOSED;
        fireChangeEvent(ProjectInformation.EVENT_CLOSE, oldStatus, status);
    
<no_super_class>