<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(self, crash, allow_duplicates = True):
 """ Add a new crash dump to the database, optionally filtering them by signature to avoid duplicates. @type crash: L{Crash} @param crash: Crash object. @type allow_duplicates: bool @param allow_duplicates: (Optional) C{True} to always add the new crash dump. C{False} to only add the crash dump if no other crash with the same signature is found in the database. Sometimes, your fuzzer turns out to be I{too} good. Then you find youself browsing through gigabytes of crash dumps, only to find a handful of actual bugs in them. This simple heuristic filter saves you the trouble by discarding crashes that seem to be similar to another one you've already found. """


        # Filter out duplicated crashes, if requested.
        if not allow_duplicates:
            signature = pickle.dumps(crash.signature, protocol = 0)
            if self._session.query(CrashDTO.id)                \
                            .filter_by(signature = signature) \
                            .count() > 0:
                return

        # Fill out a new row for the crashes table.
        crash_id = self.__add_crash(crash)

        # Fill out new rows for the memory dump.
        self.__add_memory(crash_id, crash.memoryMap)

        # On success set the row ID for the Crash object.
        # WARNING: In nested calls, make sure to delete
        # this property before a session rollback!
        crash._rowid = crash_id