docs: function bindContainer(node, containerFlags) {
              // Before we recurse into a node's children, we first save the existing parent, container
              // and block-container.  Then after we pop out of processing the children, we restore
              // these saved values.
              var saveContainer = container;
              var savedBlockScopeContainer = blockScopeContainer;
              // Depending on what kind of node this is, we may have to adjust the current container
              // and block-container.   If the current node is a container, then it is automatically
              // considered the current block-container as well.  Also, for containers that we know
              // may contain locals, we proactively initialize the .locals field. We do this because
              // it's highly likely that the .locals will be needed to place some child in (for example,
              // a parameter, or variable declaration).
              //
              // However, we do not proactively create the .locals for block-containers because it's
              // totally normal and common for block-containers to never actually have a block-scoped
              // variable in them.  We don't want to end up allocating an object for every 'block' we
              // run into when most of them won't be necessary.
              //
              // Finally, if this is a block-container, then we clear out any existing .locals object
              // it may contain within it.  This happens in incremental scenarios.  Because we can be
              // reusing a node from a previous compilation, that node may have had 'locals' created
              // for it.  We must clear this so we don't accidentally move any stale data forward from
              // a previous compilation.
              if (containerFlags & 1 /* IsContainer */) {
                  container = blockScopeContainer = node;
                  if (containerFlags & 32 /* HasLocals */) {
                      container.locals = ts.createMap();
                  }
                  addToContainerChain(container);
              }
              else if (containerFlags & 2 /* IsBlockScopedContainer */) {
                  blockScopeContainer = node;
                  blockScopeContainer.locals = undefined;
              }
              if (containerFlags & 4 /* IsControlFlowContainer */) {
                  var saveCurrentFlow = currentFlow;
                  var saveBreakTarget = currentBreakTarget;
                  var saveContinueTarget = currentContinueTarget;
                  var saveReturnTarget = currentReturnTarget;
                  var saveActiveLabels = activeLabels;
                  var saveHasExplicitReturn = hasExplicitReturn;
                  var isIIFE = containerFlags & 16 /* IsFunctionExpression */ && !!ts.getImmediatelyInvokedFunctionExpression(node);
                  // An IIFE is considered part of the containing control flow. Return statements behave
                  // similarly to break statements that exit to a label just past the statement body.
                  if (isIIFE) {
                      currentReturnTarget = createBranchLabel();
                  }
                  else {
                      currentFlow = { flags: 2 /* Start */ };
                      if (containerFlags & 16 /* IsFunctionExpression */) {
                          currentFlow.container = node;
                      }
                      currentReturnTarget = undefined;
                  }
                  currentBreakTarget = undefined;
                  currentContinueTarget = undefined;
                  activeLabels = undefined;
                  hasExplicitReturn = false;
                  bindChildren(node);
                  // Reset all reachability check related flags on node (for incremental scenarios)
                  // Reset all emit helper flags on node (for incremental scenarios)
                  node.flags &= ~4030464 /* ReachabilityAndEmitFlags */;
                  if (!(currentFlow.flags & 1 /* Unreachable */) && containerFlags & 8 /* IsFunctionLike */ && ts.nodeIsPresent(node.body)) {
                      node.flags |= 32768 /* HasImplicitReturn */;
                      if (hasExplicitReturn)
                          node.flags |= 65536 /* HasExplicitReturn */;
                  }
                  if (node.kind === 256 /* SourceFile */) {
                      node.flags |= emitFlags;
                  }
                  if (isIIFE) {
                      addAntecedent(currentReturnTarget, currentFlow);
                      currentFlow = finishFlowLabel(currentReturnTarget);
                  }
                  else {
                      currentFlow = saveCurrentFlow;
                  }
                  currentBreakTarget = saveBreakTarget;
                  currentContinueTarget = saveContinueTarget;
                  currentReturnTarget = saveReturnTarget;
                  activeLabels = saveActiveLabels;
                  hasExplicitReturn = saveHasExplicitReturn;
              }
              else if (containerFlags & 64 /* IsInterface */) {
                  seenThisKeyword = false;
                  bindChildren(node);
                  node.flags = seenThisKeyword ? node.flags | 16384 /* ContainsThis */ : node.flags & ~16384 /* ContainsThis */;
              }
              else {
                  bindChildren(node);
              }
              container = saveContainer;
              blockScopeContainer = savedBlockScopeContainer;
          }