docs: function (name /* .. [arguments] .. (callback|callbacks) */) {                                       // 537
      var self = this;                                                                                              // 538
                                                                                                                    // 539
      var params = Array.prototype.slice.call(arguments, 1);                                                        // 540
      var callbacks = {};                                                                                           // 541
      if (params.length) {                                                                                          // 542
        var lastParam = params[params.length - 1];                                                                  // 543
        if (_.isFunction(lastParam)) {                                                                              // 544
          callbacks.onReady = params.pop();                                                                         // 545
        } else if (lastParam &&                                                                                     // 546
          // XXX COMPAT WITH 1.0.3.1 onError used to exist, but now we use                                          // 547
          // onStop with an error callback instead.                                                                 // 548
          _.any([lastParam.onReady, lastParam.onError, lastParam.onStop],                                           // 549
            _.isFunction)) {                                                                                        // 550
          callbacks = params.pop();                                                                                 // 551
        }                                                                                                           // 552
      }                                                                                                             // 553
                                                                                                                    // 554
      // Is there an existing sub with the same name and param, run in an                                           // 555
      // invalidated Computation? This will happen if we are rerunning an                                           // 556
      // existing computation.                                                                                      // 557
      //                                                                                                            // 558
      // For example, consider a rerun of:                                                                          // 559
      //                                                                                                            // 560
      //     Tracker.autorun(function () {                                                                          // 561
      //       Meteor.subscribe("foo", Session.get("foo"));                                                         // 562
      //       Meteor.subscribe("bar", Session.get("bar"));                                                         // 563
      //     });                                                                                                    // 564
      //                                                                                                            // 565
      // If "foo" has changed but "bar" has not, we will match the "bar"                                            // 566
      // subcribe to an existing inactive subscription in order to not                                              // 567
      // unsub and resub the subscription unnecessarily.                                                            // 568
      //                                                                                                            // 569
      // We only look for one such sub; if there are N apparently-identical subs                                    // 570
      // being invalidated, we will require N matching subscribe calls to keep                                      // 571
      // them all active.                                                                                           // 572
      var existing = _.find(self._subscriptions, function (sub) {                                                   // 573
        return sub.inactive && sub.name === name &&                                                                 // 574
          EJSON.equals(sub.params, params);                                                                         // 575
      });                                                                                                           // 576
                                                                                                                    // 577
      var id;                                                                                                       // 578
      if (existing) {                                                                                               // 579
        id = existing.id;                                                                                           // 580
        existing.inactive = false; // reactivate                                                                    // 581
                                                                                                                    // 582
        if (callbacks.onReady) {                                                                                    // 583
          // If the sub is not already ready, replace any ready callback with the                                   // 584
          // one provided now. (It's not really clear what users would expect for                                   // 585
          // an onReady callback inside an autorun; the semantics we provide is                                     // 586
          // that at the time the sub first becomes ready, we call the last                                         // 587
          // onReady callback provided, if any.)                                                                    // 588
          if (!existing.ready)                                                                                      // 589
            existing.readyCallback = callbacks.onReady;                                                             // 590
        }                                                                                                           // 591
                                                                                                                    // 592
        // XXX COMPAT WITH 1.0.3.1 we used to have onError but now we call                                          // 593
        // onStop with an optional error argument                                                                   // 594
        if (callbacks.onError) {                                                                                    // 595
          // Replace existing callback if any, so that errors aren't                                                // 596
          // double-reported.                                                                                       // 597
          existing.errorCallback = callbacks.onError;                                                               // 598
        }                                                                                                           // 599
                                                                                                                    // 600
        if (callbacks.onStop) {                                                                                     // 601
          existing.stopCallback = callbacks.onStop;                                                                 // 602
        }                                                                                                           // 603
      } else {                                                                                                      // 604
        // New sub! Generate an id, save it locally, and send message.                                              // 605
        id = Random.id();                                                                                           // 606
        self._subscriptions[id] = {                                                                                 // 607
          id: id,                                                                                                   // 608
          name: name,                                                                                               // 609
          params: EJSON.clone(params),                                                                              // 610
          inactive: false,                                                                                          // 611
          ready: false,                                                                                             // 612
          readyDeps: new Tracker.Dependency,                                                                        // 613
          readyCallback: callbacks.onReady,                                                                         // 614
          // XXX COMPAT WITH 1.0.3.1 #errorCallback                                                                 // 615
          errorCallback: callbacks.onError,                                                                         // 616
          stopCallback: callbacks.onStop,                                                                           // 617
          connection: self,                                                                                         // 618
          remove: function() {                                                                                      // 619
            delete this.connection._subscriptions[this.id];                                                         // 620
            this.ready && this.readyDeps.changed();                                                                 // 621
          },                                                                                                        // 622
          stop: function() {                                                                                        // 623
            this.connection._send({msg: 'unsub', id: id});                                                          // 624
            this.remove();                                                                                          // 625
                                                                                                                    // 626
            if (callbacks.onStop) {                                                                                 // 627
              callbacks.onStop();                                                                                   // 628
            }                                                                                                       // 629
          }                                                                                                         // 630
        };                                                                                                          // 631
        self._send({msg: 'sub', id: id, name: name, params: params});                                               // 632
      }                                                                                                             // 633
                                                                                                                    // 634
      // return a handle to the application.                                                                        // 635
      var handle = {                                                                                                // 636
        stop: function () {                                                                                         // 637
          if (!_.has(self._subscriptions, id))                                                                      // 638
            return;                                                                                                 // 639
                                                                                                                    // 640
          self._subscriptions[id].stop();                                                                           // 641
        },                                                                                                          // 642
        ready: function () {                                                                                        // 643
          // return false if we've unsubscribed.                                                                    // 644
          if (!_.has(self._subscriptions, id))                                                                      // 645
            return false;                                                                                           // 646
          var record = self._subscriptions[id];                                                                     // 647
          record.readyDeps.depend();                                                                                // 648
          return record.ready;                                                                                      // 649
        },                                                                                                          // 650
        subscriptionId: id                                                                                          // 651
      };                                                                                                            // 652
                                                                                                                    // 653
      if (Tracker.active) {                                                                                         // 654
        // We're in a reactive computation, so we'd like to unsubscribe when the                                    // 655
        // computation is invalidated... but not if the rerun just re-subscribes                                    // 656
        // to the same subscription!  When a rerun happens, we use onInvalidate                                     // 657
        // as a change to mark the subscription "inactive" so that it can                                           // 658
        // be reused from the rerun.  If it isn't reused, it's killed from                                          // 659
        // an afterFlush.                                                                                           // 660
        Tracker.onInvalidate(function (c) {                                                                         // 661
          if (_.has(self._subscriptions, id))                                                                       // 662
            self._subscriptions[id].inactive = true;                                                                // 663
                                                                                                                    // 664
          Tracker.afterFlush(function () {                                                                          // 665
            if (_.has(self._subscriptions, id) &&                                                                   // 666
                self._subscriptions[id].inactive)                                                                   // 667
              handle.stop();                                                                                        // 668
          });                                                                                                       // 669
        });                                                                                                         // 670
      }                                                                                                             // 671
                                                                                                                    // 672
      return handle;                                                                                                // 673
    }