function Subject()
{
   this.observers = new Array();
}
Subject.prototype.Notify = function(context)
{
   var m_count = this.observers.length;
   for( var i = 0; i < m_count; i++ ){
      this.observers[i].Update( context );
   }
}
Subject.prototype.AddObserver = function(observer)
{
   if( !observer.Update )
      throw 'Wrong parameter 1';
   this.observers.push( observer );
}
Subject.prototype.RemoveObserver = function(observer)
{
   if( !observer.Update )
      throw 'Wrong parameter 2';
   this.observers._removeAt(this.observers._indexOf(observer, 0));
}
Subject.prototype._removeAt = function ( index ) {
	var m_count = this.observers.length;
            
   if ( m_count > 0 && index > -1 && index < this.observers.length ) 
   {
      switch( index )
      {
         case 0:
            this.observers.shift();
            break;
         case m_count - 1:
            this.observers.pop();
            break;
         default:
            var head   = this.observers.slice( 0, index );
            var tail   = this.observers.slice( index + 1 );
            this.observers = head.concat( tail );
            break;
      }
   }
}
Subject.prototype._indexOf = function ( object, startIndex )
{
   
   var m_count       = this.observers.length;
   var m_returnValue = - 1;
            
   if ( startIndex > -1 && startIndex < m_count ) 
   {
      var i = startIndex;

      while( i < m_count )
      {
         if ( this.observers[i] == object )
         {
            m_returnValue = i;
            break;
         }
         i++;
      }
   }
   return m_returnValue;
}
//
function inherits(base, extension)
{
   for ( var property in base )
   {
      try
      {
         extension[property] = base[property];
      }
      catch( warning ){}
   }
}