function initOpenSocialGadget(gadgetId, gadgetSpec, serverBase) {
  
  // Render gadget
  
  var gadget = gadgets.container.createGadget({'specUrl': gadgetSpec.url});
  
  gadget.id = gadgetId;
  
  gadget.setServerBase(serverBase);

  gadget.secureToken = escape(generateSecureToken(gadgetId,gadgetSpec.url));

  gadgets.container.addGadget(gadget);
  
  // KJ - the following is a bit kludged to allow proper dynamic reconfiguration of gadgets/widgets
  if (!gadgets.container.layoutManager.gadgetChromeIds_) {
      gadgets.container.layoutManager.gadgetChromeIds_ = new Array();
  }
  gadgets.container.layoutManager.gadgetChromeIds_[gadget.id] = gadgetSpec.chromeIds[0];
  //gadgets.container.layoutManager.setGadgetChromeIds(gadgetSpec.chromeIds);

  gadgets.container.renderGadget(gadget);  

};

function generateSecureToken(gadgetId,url) {
  // TODO: Use a less silly mechanism of mapping a gadget URL to an appid
  var appId = 0;
  for (var i = 0; i < url.length; i++) {
    appId += url.charCodeAt(i);
  }
  var fields = [ownerId, viewerId, appId, "shindig", url, gadgetId];
  for (var i = 0; i < fields.length; i++) {
    // escape each field individually, for metachars in URL
    fields[i] = escape(fields[i]);
  }
  return fields.join(":");
}

SampleContainerGadget = function(opt_params) {
  gadgets.IfrGadget.call(this, opt_params);
};

SampleContainerGadget.inherits(gadgets.IfrGadget);

SampleContainerGadget.prototype.getAdditionalParams = function() {
  var params = ''

  /*if (useCaja) {
    params += "&caja=1";
  }
  if (usePermissive) {
    params += "&usepermissive=1";
  }*/
  return params;
};
gadgets.container.gadgetClass = SampleContainerGadget;

function sendRequestToServer(jsonRequest, opt_callback) {
  // TODO: Should re-use the jsoncontainer code somehow
  jsonRequest = gadgets.json.stringify(jsonRequest);

  var makeRequestParams = {
    "CONTENT_TYPE" : "JSON",
    "METHOD" : "POST",
    "AUTHORIZATION" : "SIGNED",
    "POST_DATA" : encodeValues({'request' : jsonRequest,
      'st' : generateSecureToken()})};

  makeRequest(socialDataPath,
      function(data) {
        data = data.data;
        if (!data || data['error'] ||
            !data['responses'][0] || data['responses'][0]['error']) {
          alert("The request to the server caused an error.");
        } else {
          if (opt_callback) {
            opt_callback(data);
          }
        }
      },
      makeRequestParams);
};


// Xhr stuff that is copied from io.js.
// TODO: We should really get rid of the duplication
function makeXhr() {
  if (window.XMLHttpRequest) {
    return new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    var x = new ActiveXObject("Msxml2.XMLHTTP");
    if (!x) {
      x = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return x;
  }
};

function processResponse(url, callback, params, xobj) {
  if (xobj.readyState !== 4) {
    return;
  }
  if (xobj.status !== 200) {
    callback({errors : ["Error " + xobj.status] });
    return;
  }
  var txt = xobj.responseText;

    // We are using eval directly here because the outer response comes from a
  // trusted source, and json parsing is slow in IE.
  var data = eval("(" + txt + ")");
  var resp = {
    data: data
  };

  callback(resp);
};

function makeRequest(url, callback, params) {
  var xhr = makeXhr();
  xhr.open("POST", url, true);
  xhr.onreadystatechange = gadgets.util.makeClosure(
      null, processResponse, url, callback, params, xhr);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send(params.POST_DATA);
};

function encodeValues(fields, opt_noEscaping) {
  var escape = !opt_noEscaping;

  var buf = [];
  var first = false;
  for (var i in fields) if (fields.hasOwnProperty(i)) {
    if (!first) {
      first = true;
    } else {
      buf.push("&");
    }
    buf.push(escape ? encodeURIComponent(i) : i);
    buf.push("=");
    buf.push(escape ? encodeURIComponent(fields[i]) : fields[i]);
  }
  return buf.join("");
};
