--TEST--
SPL: SplObjectStorage
--FILE--
<?php

class MyObjectStorage extends SplObjectStorage
{
    function 
rewind()
    {
        echo 
__METHOD__ "()\n";
        
parent::rewind();
    }

    function 
valid()
    {
        echo 
__METHOD__ "(" . (parent::valid() ? 0) . ")\n";
        return 
parent::valid();
    }

    function 
key()
    {
        echo 
__METHOD__ "(" parent::key() . ")\n";
        return 
parent::key();
    }

    function 
current()
    {
        echo 
__METHOD__ "(" parent::current()->getName() . ")\n";
        return 
parent::current();
    }

    function 
next()
    {
        echo 
__METHOD__ "()\n";
        
parent::next();
    }
}

class 
ObserverImpl implements SplObserver
{
    protected 
$name '';

    function 
__construct($name 'obj')
    {
        
$this->name '$' $name;
    }

    function 
update(SplSubject $subject)
    {
        echo 
$this->name '->' __METHOD__ '(' $subject->getName() . ");\n";
    }
    
    function 
getName()
    {
        return 
$this->name;
    }
}

class 
SubjectImpl implements SplSubject
{
    protected 
$name '';
    protected 
$observers;

    function 
__construct($name 'sub')
    {
        
$this->observers = new MyObjectStorage;
        
$this->name '$' $name;
    }

    function 
attach(SplObserver $observer)
    {
        echo 
$this->name '->' __METHOD__ '(' $observer->getName() . ");\n";
        
$this->observers->attach($observer);
    }
    
    function 
detach(SplObserver $observer)
    {
        echo 
$this->name '->' __METHOD__ '(' $observer->getName() . ");\n";
        
$this->observers->detach($observer);
    }
    
    function 
count()
    {
        return 
$this->observers->count();
    }
    
    function 
notify()
    {
        echo 
$this->name '->' __METHOD__ "();\n";
        foreach(
$this->observers as $key => $observer)
        {
            
$observer->update($this);
        }
    }

    function 
getName()
    {
        return 
$this->name;
    }
    
    function 
contains($obj)
    {
        return 
$this->observers->contains($obj);
    }
}

$sub = new SubjectImpl;

$ob1 = new ObserverImpl("ob1");
$ob2 = new ObserverImpl("ob2");
$ob3 = new ObserverImpl("ob3");

var_dump($sub->contains($ob1));
$sub->attach($ob1);
var_dump($sub->contains($ob1));
$sub->attach($ob1);
$sub->attach($ob2);
$sub->attach($ob3);
var_dump($sub->count());

$sub->notify();

$sub->detach($ob3);
var_dump($sub->count());

$sub->notify();

$sub->detach($ob2);
$sub->detach($ob1);
var_dump($sub->count());

$sub->notify();

$sub->attach($ob3);
var_dump($sub->count());

$sub->notify();

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
bool(false)
$sub->SubjectImpl::attach($ob1);
bool(true)
$sub->SubjectImpl::attach($ob1);
$sub->SubjectImpl::attach($ob2);
$sub->SubjectImpl::attach($ob3);
int(3)
$sub->SubjectImpl::notify();
MyObjectStorage::rewind()
MyObjectStorage::valid(1)
MyObjectStorage::current($ob1)
MyObjectStorage::key(0)
$ob1->ObserverImpl::update($sub);
MyObjectStorage::next()
MyObjectStorage::valid(1)
MyObjectStorage::current($ob2)
MyObjectStorage::key(1)
$ob2->ObserverImpl::update($sub);
MyObjectStorage::next()
MyObjectStorage::valid(1)
MyObjectStorage::current($ob3)
MyObjectStorage::key(2)
$ob3->ObserverImpl::update($sub);
MyObjectStorage::next()
MyObjectStorage::valid(0)
$sub->SubjectImpl::detach($ob3);
int(2)
$sub->SubjectImpl::notify();
MyObjectStorage::rewind()
MyObjectStorage::valid(1)
MyObjectStorage::current($ob1)
MyObjectStorage::key(0)
$ob1->ObserverImpl::update($sub);
MyObjectStorage::next()
MyObjectStorage::valid(1)
MyObjectStorage::current($ob2)
MyObjectStorage::key(1)
$ob2->ObserverImpl::update($sub);
MyObjectStorage::next()
MyObjectStorage::valid(0)
$sub->SubjectImpl::detach($ob2);
$sub->SubjectImpl::detach($ob1);
int(0)
$sub->SubjectImpl::notify();
MyObjectStorage::rewind()
MyObjectStorage::valid(0)
$sub->SubjectImpl::attach($ob3);
int(1)
$sub->SubjectImpl::notify();
MyObjectStorage::rewind()
MyObjectStorage::valid(1)
MyObjectStorage::current($ob3)
MyObjectStorage::key(0)
$ob3->ObserverImpl::update($sub);
MyObjectStorage::next()
MyObjectStorage::valid(0)
===DONE===