text: // This file contains the HTTP Req Abs, Repo API and getRepo
  // portions of Top Level API from github.com/michael/github.js
  
  // ORIGINAL LIB:
  // Github.js 0.7.0
  // (c) 2012 Michael Aufreiter, Development Seed
  // Github.js is freely distributable under the MIT license.
  // For all details and documentation:
  // http://substance.io/michael/github
  
  (function() {
    var Github;
    var API_URL = 'https://api.github.com';
  
    Github = window.Github = function(options) {
  
      // HTTP Request Abstraction
      // =======
      // 
      // I'm not proud of this and neither should you be if you were responsible for the XMLHttpRequest spec.
  
      function _request(method, path, data, cb, raw) {
        function getURL() {
          var url = API_URL + path;
          return url + ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime();
        }
  
        var xhr = new XMLHttpRequest();
        if (!raw) {xhr.dataType = "json"}
  
        xhr.open(method, getURL());
        xhr.onreadystatechange = function () {
          if (this.readyState == 4) {
            if (this.status >= 200 && this.status < 300 || this.status === 304) {
              cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true);
            } else {
              cb({request: this, error: this.status});
            }
          }
        }
        xhr.setRequestHeader('Accept','application/vnd.github.raw');
        xhr.setRequestHeader('Content-Type','application/json;charset=UTF-8');
        if (
           (options.auth == 'oauth' && options.token) ||
           (options.auth == 'basic' && options.username && options.password)
           ) {
             xhr.setRequestHeader('Authorization',options.auth == 'oauth'
               ? 'token '+ options.token
               : 'Basic ' + Base64.encode(options.username + ':' + options.password)
             );
           }
        data ? xhr.send(JSON.stringify(data)) : xhr.send();
      }
  
      // Repository API
      // =======
  
      Github.Repository = function(options) {
        var repo = options.name;
        var user = options.user;
        
        var that = this;
        var repoPath = "/repos/" + user + "/" + repo;
  
        var currentTree = {
          "branch": null,
          "sha": null
        };
  
        // Uses the cache if branch has not been changed
        // -------
  
        function updateTree(branch, cb) {
          if (branch === currentTree.branch && currentTree.sha) return cb(null, currentTree.sha);
          that.getRef("heads/"+branch, function(err, sha) {
            currentTree.branch = branch;
            currentTree.sha = sha;
            cb(err, sha);
          });
        }
  
        // Get a particular reference
        // -------
  
        this.getRef = function(ref, cb) {
          _request("GET", repoPath + "/git/refs/" + ref, null, function(err, res) {
            if (err) return cb(err);
            cb(null, res.object.sha);
          });
        };
  
        // Create a new reference
        // --------
        //
        // {
        //   "ref": "refs/heads/my-new-branch-name",
        //   "sha": "827efc6d56897b048c772eb4087f854f46256132"
        // }
  
        this.createRef = function(options, cb) {
          _request("POST", repoPath + "/git/refs", options, cb);
        };
  
        // Delete a reference
        // --------
        // 
        // repo.deleteRef('heads/gh-pages')
        // repo.deleteRef('tags/v1.0')
  
        this.deleteRef = function(ref, cb) {
          _request("DELETE", repoPath + "/git/refs/"+ref, options, cb);
        };
  
        // List all branches of a repository
        // -------
  
        this.listBranches = function(cb) {
          _request("GET", repoPath + "/git/refs/heads", null, function(err, heads) {
            if (err) return cb(err);
            cb(null, _.map(heads, function(head) { return _.last(head.ref.split('/')); }));
          });
        };
  
        // Retrieve the contents of a blob
        // -------
  
        this.getBlob = function(sha, cb) {
          _request("GET", repoPath + "/git/blobs/" + sha, null, cb, 'raw');
        };
  
        // For a given file path, get the corresponding sha (blob for files, tree for dirs)
        // -------
  
        this.getSha = function(branch, path, cb) {
          // Just use head if path is empty
          if (path === "") return that.getRef("heads/"+branch, cb);
          that.getTree(branch+"?recursive=true", function(err, tree) {
            var file = _.select(tree, function(file) {
              return file.path === path;
            })[0];
            cb(null, file ? file.sha : null);
          });
        };
  
        // Retrieve the tree a commit points to
        // -------
  
        this.getTree = function(tree, cb) {
          _request("GET", repoPath + "/git/trees/"+tree, null, function(err, res) {
            if (err) return cb(err);
            cb(null, res.tree);
          });
        };
  
        // Post a new blob object, getting a blob SHA back
        // -------
  
        this.postBlob = function(content, cb) {
          if (typeof(content) === "string") {
            content = {
              "content": content,
              "encoding": "base64"
            };
          }
  
          _request("POST", repoPath + "/git/blobs", content, function(err, res) {
            if (err) return cb(err);
            cb(null, res.sha);
          });
        };
  
        // Update an existing tree adding a new blob object getting a tree SHA back
        // -------
  
        this.updateTree = function(baseTree, path, blob, cb) {
          var data = {
            "base_tree": baseTree,
            "tree": [
              {
                "path": path,
                "mode": "100644",
                "type": "blob",
                "sha": blob
              }
            ]
          };
          _request("POST", repoPath + "/git/trees", data, function(err, res) {
            if (err) return cb(err);
            cb(null, res.sha);
          });
        };
  
        // Post a new tree object having a file path pointer replaced
        // with a new blob SHA getting a tree SHA back
        // -------
  
        this.postTree = function(tree, cb) {
          _request("POST", repoPath + "/git/trees", { "tree": tree }, function(err, res) {
            if (err) return cb(err);
            cb(null, res.sha);
          });
        };
  
        // Create a new commit object with the current commit SHA as the parent
        // and the new tree SHA, getting a commit SHA back
        // -------
  
        this.commit = function(parent, tree, message, cb) {
          var data = {
            "message": message,
            "author": {
  //          "name": options.username,
              "name": "ICEcoder",
              "email": "info@icecoder.net"
            },
            "parents": [
              parent
            ],
            "tree": tree
          };
  
          _request("POST", repoPath + "/git/commits", data, function(err, res) {
            currentTree.sha = res.sha; // update latest commit
            if (err) return cb(err);
            cb(null, res.sha);
          });
        };
  
        // Update the reference of your head to point to the new commit SHA
        // -------
  
        this.updateHead = function(head, commit, cb) {
          _request("PATCH", repoPath + "/git/refs/heads/" + head, { "sha": commit }, function(err, res) {
            cb(err);
          });
        };
  
        // Show repository information
        // -------
  
        this.show = function(cb) {
          _request("GET", repoPath, null, cb);
        };
  
        // Get contents
        // --------
  
        this.contents = function(path, cb) {
          _request("GET", repoPath + "/contents", { path: path }, cb);
        };
  
        // Fork repository
        // -------
  
        this.fork = function(cb) {
          _request("POST", repoPath + "/forks", null, cb);
        };
  
        // Create pull request
        // --------
  
        this.createPullRequest = function(options, cb) {
          _request("POST", repoPath + "/pulls", options, cb);
        };
  
        // Read file at given path
        // -------
  
        this.read = function(branch, path, cb) {
          that.getSha(branch, path, function(err, sha) {
            if (!sha) return cb("not found", null);
            that.getBlob(sha, function(err, content) {
              cb(err, content, sha);
            });
          });
        };
  
        // Remove a file from the tree
        // -------
  
        this.remove = function(branch, path, cb) {
          updateTree(branch, function(err, latestCommit) {
            that.getTree(latestCommit+"?recursive=true", function(err, tree) {
              // Update Tree
              var newTree = _.reject(tree, function(ref) { return ref.path === path });
              _.each(newTree, function(ref) {
                if (ref.type === "tree") delete ref.sha;
              });
  
              that.postTree(newTree, function(err, rootTree) {
                that.commit(latestCommit, rootTree, 'Deleted '+path , function(err, commit) {
                  that.updateHead(branch, commit, function(err) {
                    cb(err);
                  });
                });
              });
            });
          });
        };
  
        // Move a file to a new location
        // -------
  
        this.move = function(branch, path, newPath, cb) {
          updateTree(branch, function(err, latestCommit) {
            that.getTree(latestCommit+"?recursive=true", function(err, tree) {
              // Update Tree
              _.each(tree, function(ref) {
                if (ref.path === path) ref.path = newPath;
                if (ref.type === "tree") delete ref.sha;
              });
  
              that.postTree(tree, function(err, rootTree) {
                that.commit(latestCommit, rootTree, 'Deleted '+path , function(err, commit) {
                  that.updateHead(branch, commit, function(err) {
                    cb(err);
                  });
                });
              });
            });
          });
        };
  
        // Write file contents to a given branch and path
        // -------
  
        this.write = function(branch, path, content, message, cb) {
          updateTree(branch, function(err, latestCommit) {
            if (err) return cb(err);
            that.postBlob(content, function(err, blob) {
              if (err) return cb(err);
              that.updateTree(latestCommit, path, blob, function(err, tree) {
                if (err) return cb(err);
                that.commit(latestCommit, tree, message, function(err, commit) {
                  if (err) return cb(err);
                  that.updateHead(branch, commit, cb);
                });
              });
            });
          });
        };
      };
  
      // Gists API
      // =======
  
      Github.Gist = function(options) {
        var id = options.id;
        var that = this;
        var gistPath = "/gists/"+id;
  
        // Read the gist
        // --------
  
        this.read = function(cb) {
          _request("GET", gistPath, null, function(err, gist) {
            cb(err, gist);
          });
        };
  
  
        // Delete the gist
        // --------
  
        this.delete = function(cb) {
          _request("DELETE", gistPath, null, function(err,res) {
            cb(err,res);
          });
        };
  
        // Fork a gist
        // --------
  
        this.fork = function(cb) {
          _request("POST", gistPath+"/fork", null, function(err,res) {
            cb(err,res);
          });
        };
  
        // Update a gist with the new stuff
        // --------
  
        this.update = function(options, cb) {
          _request("PATCH", gistPath, options, function(err,res) {
            cb(err,res);
          });
        };
      };
  
      // Top Level API
      // -------
  
      this.getRepo = function(user, repo) {
        return new Github.Repository({user: user, name: repo});
      };
  
  Github.User = function(token) {
  console.log(token);
      this.validate = function(cb) {
         _request("GET", "/applications/"+token+"/tokens/", function(err, res) {
  		console.log(err);
  		console.log(res);
             cb(err,res);
          });
      };
  }
  
  	this.getUser = function(token) {
        return new Github.User(token);
      };
  
  
  
    };
  }).call(this);