public function garbageCollect( $keyOrObject = null )
    {

        // we're going to be doing the $this->instancesPersisted_max_allowed check first
        if( $keyOrObject == null ) {

            // auto garbage collection is disabled.
            if( !is_int( $this->instancesMaxAllowed ) ) {
                return 0;
            }

            $removed = 0;

            reset( $this->instancesPersisted );

            // iterate over the instances starting oldest first while we've got too many
            while( count( $this->instancesPersisted ) >= $this->instancesMaxAllowed && list( $key, $obj ) = each( $this->instancesPersisted ) ) {

                if( !$obj->isChanged() ) {

                    unset( $this->instancesPersisted[$key] );
                    $removed++;

                }

            }

            return $removed;

        }

        if( is_object( $keyOrObject ) ) {

            foreach( $this->instancesPersisted as $key => $obj ) {

                if( $keyOrObject === $obj ) {

                    if( $obj->isChanged() ) {
                        return 0;
                    } else {
                        unset( $this->instancesPersisted[$key] );
                        return 1;
                    }

                }

            }

            // remove from static unpersisted
            if( false !== $_key = array_search( $keyOrObject, $this->instancesUnpersisted, true ) ) {
                unset( $this->instancesUnpersisted[$_key] );
            }

        } elseif( is_scalar( $keyOrObject ) && isset( $this->instancesPersisted[$keyOrObject] ) ) {

            if( $this->instancesPersisted[$keyOrObject]->isChanged() ) {
                return 0;
            } else {
                unset( $this->instancesPersisted[$keyOrObject] );
                return 1;
            }

        }

        return 0;

    }