function oAuthCallback(data) {
  //TODO - verify that "data" contains valid access_token, etc. and not an error message.

  trackAction(activeFlow,'submit','facebookConnect');

  //post the oauth token to the servlet for verification/connecting account, etc.
  $.post('/flowController?submitAction=facebookValidateOAuth&' + data, null, function(responseData) {
    activeFlow.evaluateAuthorization();
  });
}

function doFacebookLoginOAuth(flowPath) {
  if (activeFlow) {
    trackAction(activeFlow,'load','facebookConnect');

    //clear any active timeouts - e.g. if we had a message temporarily displayed, make sure that the timeout callback isn't triggered.
    clearTimeout(activeFlow.flowTimeout);
  } else {
    trackAction(getFlow('loginContainer',flowPath),'load','facebookConnect');
  }


  var scheme = ("https:" == document.location.protocol) ? "https://" : "http://";
  url = "https://www.facebook.com/dialog/oauth?client_id=" +
           facebookAppId  + "&response_type=token&redirect_uri=" + scheme + window.location.hostname + "/fb/connect/receiver_oauth.jsp";
  window.open(url);

}

function doFacebookLogin(flowPath) {
    //TODO - container parameter? how to determine login vs. register flow?
    if (activeFlow) {
      trackAction(activeFlow,'load','facebookConnect');
    } else {
      trackAction(getFlow('loginContainer',flowPath),'load','facebookConnect');
    }
      //note, activeFlow should now be set.

      try {
        FB_RequireFeatures(["Connect"], function(){
        FB.init(facebookApiKey, "/fb/connect/receiver.jsp");

        //FB.Connect.logout();
        //TODO wrapping in a loggout would ensure that if we are actually logged in, we will log out first.  Otherwise, the "Connect" button does nothing
        //Alternatively, we could automatically log them back into VM with their FB credentials
        //FB.Connect.logout(function() {

          FB.Connect.requireSession(function() {
    //       if (requestExtendedPermissions()) {
    //          FB.Connect.showPermissionDialog("publish_stream", function(data) {
    //            saveExtendedPermissions(data);
    //            activeFlow.evaluateAuthorization();
    //          });
    //        } else {
              trackAction(activeFlow,'submit','facebookConnect');
              activeFlow.evaluateAuthorization();
    //        }
          });
        });
      } catch (err) {
        //ignore facebook api errors.
        //TODO - handle with a modal dialog
      }

}

function saveExtendedPermissions(data) {
  $.ajax({url :"/flowController",
        type : "POST",
        data : {extendedPermissions : data, submitAction : "facebookSaveExtendedPermissions"},
        global : false});
}

function requestExtendedPermissions() {
  var data = $.ajax({url :"/flowController?actionType=facebookCheckExtendedPermissions",
        type : "GET",
        dataType : "json",
        global : false,
        async : false});

  if (data.status == 'success') {
    return true;
  } else {
    return false;
  }
}

function facebookLogout(logoutUrl) {
  try {
    initializeFacebookApi();
    FB_RequireFeatures(["Connect"], function(){
      FB.init(facebookApiKey, "/fb/connect/receiver.jsp");
      FB.ensureInit(function() {
        FB.Connect.ifUserConnected(
            function() {
              FB.Connect.logout(function(data) {
                window.location = '/post/logout.jsp'; return false;;
              });
            },
            logoutUrl);
        });
      });
  } catch (err) {
    //ignore fb errors
  }

  //if we have reached this point, something has gone wrong with fb. Send the user to the logout page and hope for the best.
  window.location = '/post/logout.jsp';
}
