(function($) {
  
  var fadeQueue = 'fadeQueue';
  
  $.fn[ fadeQueue ] = function( start, delay, speed ) {
    return this.each(function(){
      var that = $(this),
        data;
      
      // Get the per-element fadeQueue data store, or create it if necessary.
      that.data( fadeQueue, data = that.data( fadeQueue ) || {} );
      
      // Actually perform the append + fade bit, you know, the good stuff!
      function fade( speed ) {
        that.children(':first')
          .hide()
          .appendTo( that )
          .fadeIn( speed );
      };
      
      // Only fade speed was specified, so fade once and exit.
      if ( typeof start !== 'boolean' ) {
        return fade( start );
      }
      
      // Clear any pending timeout for this element.
      if ( data.id ) {
        clearTimeout( data.id );
        delete data.id;
      }
      
      // Fade immediately and start the loop.
      start && (function loopy(){
        fade( speed );
        data.id = setTimeout( loopy, delay );
      })();
      
    });
  };
  
})(jQuery);
