diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index 8492a67191..37794c5fe3 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -28,7 +28,9 @@
 		"github.com/docker/machine/drivers/vmwarevsphere/errors",
 		"github.com/docker/machine/libmachine",
 		"github.com/docker/machine/libmachine/auth",
+		"github.com/docker/machine/libmachine/bugsnag",
 		"github.com/docker/machine/libmachine/cert",
+		"github.com/docker/machine/libmachine/check",
 		"github.com/docker/machine/libmachine/drivers",
 		"github.com/docker/machine/libmachine/drivers/plugin",
 		"github.com/docker/machine/libmachine/drivers/plugin/localbinary",
@@ -39,6 +41,7 @@
 		"github.com/docker/machine/libmachine/hosttest",
 		"github.com/docker/machine/libmachine/libmachinetest",
 		"github.com/docker/machine/libmachine/log",
+		"github.com/docker/machine/libmachine/mcndockerclient",
 		"github.com/docker/machine/libmachine/mcnerror",
 		"github.com/docker/machine/libmachine/mcnflag",
 		"github.com/docker/machine/libmachine/mcnutils",
@@ -56,9 +59,22 @@
 	],
 	"Deps": [
 		{
-		  "ImportPath": "github.com/Sirupsen/logrus",
-		  "Comment": "v0.8.7-49-gcdaedc6",
-		  "Rev": "cdaedc68f2894175ac2b3221869685602c759e71"
+			"ImportPath": "github.com/Sirupsen/logrus",
+			"Comment": "v0.8.7-49-gcdaedc6",
+			"Rev": "cdaedc68f2894175ac2b3221869685602c759e71"
+		},
+		{
+			"ImportPath": "github.com/bugsnag/bugsnag-go",
+			"Comment": "v1.0.5-19-g02e9528",
+			"Rev": "02e952891c52fbcb15f113d90633897355783b6e"
+		},
+		{
+			"ImportPath": "github.com/bugsnag/osext",
+			"Rev": "0dd3f918b21bec95ace9dc86c7e70266cfc5c702"
+		},
+		{
+			"ImportPath": "github.com/bugsnag/panicwrap",
+			"Rev": "e5f9854865b9778a45169fc249e99e338d4d6f27"
 		},
 		{
 			"ImportPath": "github.com/MSOpenTech/azure-sdk-for-go",
diff --git a/vendor/github.com/bugsnag/bugsnag-go/.travis.yml b/vendor/github.com/bugsnag/bugsnag-go/.travis.yml
new file mode 100644
index 0000000000..0d567658c6
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/.travis.yml
@@ -0,0 +1,11 @@
+sudo: false
+language: go
+
+go:
+  - 1.3
+  - 1.4
+  - 1.5
+  - tip
+
+script:
+  - make ci
diff --git a/vendor/github.com/bugsnag/bugsnag-go/CHANGELOG.md b/vendor/github.com/bugsnag/bugsnag-go/CHANGELOG.md
new file mode 100644
index 0000000000..79f736f00f
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/CHANGELOG.md
@@ -0,0 +1,22 @@
+1.0.4
+-----
+
+- Fix appengine integration broken by 1.0.3
+
+1.0.3
+-----
+
+- Allow any Logger with a Printf method.
+
+1.0.2
+-----
+
+- Use bugsnag copies of dependencies to avoid potential link rot
+
+1.0.1
+-----
+
+- gofmt/golint/govet docs improvements.
+
+1.0.0
+-----
diff --git a/vendor/github.com/bugsnag/bugsnag-go/CONTRIBUTING.md b/vendor/github.com/bugsnag/bugsnag-go/CONTRIBUTING.md
new file mode 100644
index 0000000000..a665b401e6
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/CONTRIBUTING.md
@@ -0,0 +1,78 @@
+Contributing
+============
+
+-   [Fork](https://help.github.com/articles/fork-a-repo) the [notifier on github](https://github.com/bugsnag/bugsnag-go)
+-   Build and test your changes
+-   Commit and push until you are happy with your contribution
+-   [Make a pull request](https://help.github.com/articles/using-pull-requests)
+-   Thanks!
+
+
+Installing the go development environment
+-------------------------------------
+
+1.  Install homebrew
+
+    ```
+    ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
+    ```
+
+1. Install go
+
+    ```
+    brew install go --cross-compile-all
+    ```
+
+1. Configure `$GOPATH` in `~/.bashrc`
+
+    ```
+    export GOPATH="$HOME/go"
+    export PATH=$PATH:$GOPATH/bin
+    ```
+
+Installing the appengine development environment
+------------------------------------------------
+
+1. Follow the [Google instructions](https://cloud.google.com/appengine/downloads).
+
+Downloading the code
+--------------------
+
+You can download the code and its dependencies using
+
+```
+go get -t github.com/bugsnag/bugsnag-go
+```
+
+It will be put into "$GOPATH/src/github.com/bugsnag/bugsnag-go"
+
+Then install depend
+
+
+Running Tests
+-------------
+
+You can run the tests with
+
+```shell
+go test
+```
+
+If you've made significant changes, please also test the appengine integration with
+
+```shell
+goapp test
+```
+
+Releasing a New Version
+-----------------------
+
+If you are a project maintainer, you can build and release a new version of
+`bugsnag-go` as follows:
+
+1. Commit all your changes.
+2. Update the version number in `bugsnag.go`.
+3. Add an entry to `CHANGELOG.md` and update the README if necessary.
+4. commit tag and push
+
+    git commit -mv1.0.x && git tag v1.0.x && git push origin v1.0.x
diff --git a/vendor/github.com/bugsnag/bugsnag-go/LICENSE.txt b/vendor/github.com/bugsnag/bugsnag-go/LICENSE.txt
new file mode 100644
index 0000000000..3cb0ec0fff
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Bugsnag
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/bugsnag/bugsnag-go/Makefile b/vendor/github.com/bugsnag/bugsnag-go/Makefile
new file mode 100644
index 0000000000..70ec732320
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/Makefile
@@ -0,0 +1,30 @@
+TEST?=./...
+
+default: alldeps test
+
+deps:
+	go get -v -d ./...
+
+alldeps:
+	go get -v -d -t ./...
+
+updatedeps:
+	go get -v -d -u ./...
+
+test: alldeps
+	go test
+	@go vet 2>/dev/null ; if [ $$? -eq 3 ]; then \
+		go get golang.org/x/tools/cmd/vet; \
+	fi
+	@go vet $(TEST) ; if [ $$? -eq 1 ]; then \
+		echo "go-vet: Issues running go vet ./..."; \
+		exit 1; \
+	fi
+
+ci: alldeps test
+
+bench:
+	go test --bench=.*
+
+
+.PHONY: bin checkversion ci default deps generate releasebin test testacc testrace updatedeps
diff --git a/vendor/github.com/bugsnag/bugsnag-go/README.md b/vendor/github.com/bugsnag/bugsnag-go/README.md
new file mode 100644
index 0000000000..60ddc9976e
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/README.md
@@ -0,0 +1,553 @@
+# Bugsnag Notifier for Golang
+[](https://github.com/bugsnag/bugsnag-go/releases)
+[](https://travis-ci.org/bugsnag/bugsnag-go)
+[](http://godoc.org/github.com/bugsnag/bugsnag-go)
+
+The Bugsnag Notifier for Golang gives you instant notification of panics, or
+unexpected errors, in your golang app. Any unhandled panics will trigger a
+notification to be sent to your Bugsnag project.
+
+[Bugsnag](http://bugsnag.com) captures errors in real-time from your web,
+mobile and desktop applications, helping you to understand and resolve them
+as fast as possible. [Create a free account](http://bugsnag.com) to start
+capturing exceptions from your applications.
+
+## How to Install
+
+1. Download the code
+
+    ```shell
+    go get github.com/bugsnag/bugsnag-go
+    ```
+
+### Using with net/http apps
+
+For a golang app based on [net/http](https://godoc.org/net/http), integrating
+Bugsnag takes two steps. You should also use these instructions if you're using
+the [gorilla toolkit](http://www.gorillatoolkit.org/), or the
+[pat](https://github.com/bmizerany/pat/) muxer.
+
+1. Configure bugsnag at the start of your `main()` function:
+
+    ```go
+    import "github.com/bugsnag/bugsnag-go"
+
+    func main() {
+        bugsnag.Configure(bugsnag.Configuration{
+            APIKey: "YOUR_API_KEY_HERE",
+            ReleaseStage: "production",
+            // more configuration options
+        })
+
+        // rest of your program.
+    }
+    ```
+
+2. Wrap your server in a [bugsnag.Handler](https://godoc.org/github.com/bugsnag/bugsnag-go/#Handler)
+
+    ```go
+    // a. If you're using the builtin http mux, you can just pass
+    //    bugsnag.Handler(nil) to http.ListenAndServer
+    http.ListenAndServe(":8080", bugsnag.Handler(nil))
+
+    // b. If you're creating a server manually yourself, you can set
+    //    its handlers the same way
+    srv := http.Server{
+        Handler: bugsnag.Handler(nil)
+    }
+
+    // c. If you're not using the builtin http mux, wrap your own handler
+    // (though make sure that it doesn't already catch panics)
+    http.ListenAndServe(":8080", bugsnag.Handler(handler))
+    ```
+
+### Using with Revel apps
+
+There are two steps to get panic handling in [revel](https://revel.github.io) apps.
+
+1. Add the `bugsnagrevel.Filter` immediately after the `revel.PanicFilter` in `app/init.go`:
+
+    ```go
+
+    import "github.com/bugsnag/bugsnag-go/revel"
+
+    revel.Filters = []revel.Filter{
+        revel.PanicFilter,
+        bugsnagrevel.Filter,
+        // ...
+    }
+    ```
+
+2. Set bugsnag.apikey in the top section of `conf/app.conf`.
+
+    ```
+    module.static=github.com/revel/revel/modules/static
+
+    bugsnag.apikey=YOUR_API_KEY_HERE
+
+    [dev]
+    ```
+
+### Using with martini apps
+
+1. Add `bugsnagmartini.AutoNotify` immediately after the `martini.Recovery` middleware in `main.go`.
+This causes unhandled panics to notify bugsnag.
+
+    ```go
+
+    import "github.com/bugsnag/bugsnag-go/martini"
+
+    func main() {
+
+        m.Use(martini.Recover()
+
+        m.Use(bugsnagmartini.AutoNotify(bugsnag.Configuration{
+            APIKey: "YOUR_API_KEY_HERE",
+        }))
+    }
+    ```
+
+2. Use `bugsnag` from the context injection if you need to notify about non-fatal errors.
+
+    ```
+    func MyHandler(r *http.Request, bugsnag *bugsnag.Notifier) string {
+        bugsnag.Notify(err);
+    }
+    ```
+
+### Using with Google App Engine
+
+1. Configure bugsnag at the start of your `init()` function:
+
+    ```go
+    import "github.com/bugsnag/bugsnag-go"
+
+    func init() {
+        bugsnag.Configure(bugsnag.Configuration{
+            APIKey: "YOUR_API_KEY_HERE",
+        })
+
+        // ...
+    }
+    ```
+
+2. Wrap *every* http.Handler or http.HandlerFunc with Bugsnag:
+
+    ```go
+    // a. If you're using HandlerFuncs
+    http.HandleFunc("/", bugsnag.HandlerFunc(
+        func (w http.ResponseWriter, r *http.Request) {
+            // ...
+        }))
+
+    // b. If you're using Handlers
+    http.Handle("/", bugsnag.Handler(myHttpHandler))
+    ```
+
+3. In order to use Bugsnag, you must provide the current
+[`appengine.Context`](https://developers.google.com/appengine/docs/go/reference#Context), or
+current `*http.Request` as rawData (This is done automatically for `bugsnag.Handler` and `bugsnag.HandlerFunc`).
+The easiest way to do this is to create a new instance of the notifier.
+
+    ```go
+    c := appengine.NewContext(r)
+    notifier := bugsnag.New(c)
+
+    if err != nil {
+        notifier.Notify(err)
+    }
+
+    go func () {
+        defer notifier.Recover()
+
+        // ...
+    }()
+    ```
+
+
+## Notifying Bugsnag manually
+
+Bugsnag will automatically handle any panics that crash your program and notify
+you of them. If you've integrated with `revel` or `net/http`, then you'll also
+be notified of any panics() that happen while processing a request.
+
+Sometimes however it's useful to manually notify Bugsnag of a problem. To do this,
+call [`bugsnag.Notify()`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Notify)
+
+```go
+if err != nil {
+    bugsnag.Notify(err)
+}
+```
+
+### Manual panic handling
+
+To avoid a panic in a goroutine from crashing your entire app, you can use
+[`bugsnag.Recover()`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Recover)
+to stop a panic from unwinding the stack any further. When `Recover()` is hit,
+it will send any current panic to Bugsnag and then stop panicking. This is
+most useful at the start of a goroutine:
+
+```go
+go func() {
+    defer bugsnag.Recover()
+
+    // ...
+}()
+```
+
+Alternatively you can use
+[`bugsnag.AutoNotify()`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Recover)
+to notify bugsnag of a panic while letting the program continue to panic. This
+is useful if you're using a Framework that already has some handling of panics
+and you are retrofitting bugsnag support.
+
+```go
+defer bugsnag.AutoNotify()
+```
+
+## Sending Custom Data
+
+Most functions in the Bugsnag API, including `bugsnag.Notify()`,
+`bugsnag.Recover()`, `bugsnag.AutoNotify()`, and `bugsnag.Handler()` let you
+attach data to the notifications that they send. To do this you pass in rawData,
+which can be any of the supported types listed here. To add support for more
+types of rawData see [OnBeforeNotify](#custom-data-with-onbeforenotify).
+
+### Custom MetaData
+
+Custom metaData appears as tabs on Bugsnag.com. You can set it by passing
+a [`bugsnag.MetaData`](https://godoc.org/github.com/bugsnag/bugsnag-go/#MetaData)
+object as rawData.
+
+```go
+bugsnag.Notify(err,
+    bugsnag.MetaData{
+        "Account": {
+            "Name": Account.Name,
+            "Paying": Account.Plan.Premium,
+        },
+    })
+```
+
+### Request data
+
+Bugsnag can extract interesting data from
+[`*http.Request`](https://godoc.org/net/http/#Request) objects, and
+[`*revel.Controller`](https://godoc.org/github.com/revel/revel/#Controller)
+objects. These are automatically passed in when handling panics, and you can
+pass them yourself.
+
+```go
+func (w http.ResponseWriter, r *http.Request) {
+    bugsnag.Notify(err, r)
+}
+```
+
+### User data
+
+User data is searchable, and the `Id` powers the count of users affected. You
+can set which user an error affects by passing a
+[`bugsnag.User`](https://godoc.org/github.com/bugsnag/bugsnag-go/#User) object as
+rawData.
+
+```go
+bugsnag.Notify(err,
+    bugsnag.User{Id: "1234", Name: "Conrad", Email: "me@cirw.in"})
+```
+
+### Error Class
+
+Errors in your Bugsnag dashboard are grouped by their "error class" and by line number.
+You can override the error class by passing a
+[`bugsnag.ErrorClass`](https://godoc.org/github.com/bugsnag/bugsnag-go/#ErrorClass) object as
+rawData.
+
+```go
+bugsnag.Notify(err, bugsnag.ErrorClass{"I/O Timeout"})
+```
+
+### Context
+
+The context shows up prominently in the list view so that you can get an idea
+of where a problem occurred. You can set it by passing a
+[`bugsnag.Context`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Context)
+object as rawData.
+
+```go
+bugsnag.Notify(err, bugsnag.Context{"backgroundJob"})
+```
+
+### Severity
+
+Bugsnag supports three severities, `SeverityError`, `SeverityWarning`, and `SeverityInfo`.
+You can set the severity of an error by passing one of these objects as rawData.
+
+```go
+bugsnag.Notify(err, bugsnag.SeverityInfo)
+```
+
+## Configuration
+
+You must call `bugsnag.Configure()` at the start of your program to use Bugsnag, you pass it
+a [`bugsnag.Configuration`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Configuration) object
+containing any of the following values.
+
+### APIKey
+
+The Bugsnag API key can be found on your [Bugsnag dashboard](https://bugsnag.com) under "Settings".
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    APIKey: "YOUR_API_KEY_HERE",
+})
+```
+
+### Endpoint
+
+The Bugsnag endpoint defaults to `https://notify.bugsnag.com/`. If you're using Bugsnag enterprise,
+you should set this to the endpoint of your local instance.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    Endpoint: "http://bugsnag.internal:49000/",
+})
+```
+
+### ReleaseStage
+
+The ReleaseStage tracks where your app is deployed. You should set this to `production`, `staging`,
+`development` or similar as appropriate.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    ReleaseStage: "development",
+})
+```
+
+### NotifyReleaseStages
+
+The list of ReleaseStages to notify in. By default Bugsnag will notify you in all release stages, but
+you can use this to silence development errors.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    NotifyReleaseStages: []string{"production", "staging"},
+})
+```
+
+### AppVersion
+
+If you use a versioning scheme for deploys of your app, Bugsnag can use the `AppVersion` to only
+re-open errors if they occur in later version of the app.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    AppVersion: "1.2.3",
+})
+```
+
+### Hostname
+
+The hostname is used to track where exceptions are coming from in the Bugsnag dashboard. The
+default value is obtained from `os.Hostname()` so you won't often need to change this.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    Hostname: "go1",
+})
+```
+
+### ProjectPackages
+
+In order to determine where a crash happens Bugsnag needs to know which packages you consider to
+be part of your app (as opposed to a library). By default this is set to `[]string{"main*"}`. Strings
+are matched to package names using [`filepath.Match`](http://godoc.org/path/filepath#Match).
+
+For matching subpackages within a package you may use the `**` notation. For example, `github.com/domain/package/**` will match all subpackages under `package/`.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    ProjectPackages: []string{"main", "github.com/domain/myapp/*"},
+}
+```
+
+### ParamsFilters
+
+Sometimes sensitive data is accidentally included in Bugsnag MetaData. You can remove it by
+setting `ParamsFilters`. Any key in the `MetaData` that includes any string in the filters
+will be redacted. The default is `[]string{"password", "secret"}`, which prevents fields like
+`password`, `password_confirmation` and `secret_answer` from being sent.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    ParamsFilters: []string{"password", "secret"},
+}
+```
+
+### Logger
+
+The Logger to write to in case of an error inside Bugsnag. This defaults to the global logger.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    Logger: app.Logger,
+}
+```
+
+### PanicHandler
+
+The first time Bugsnag is configured, it wraps the running program in a panic
+handler using [panicwrap](http://godoc.org/github.com/ConradIrwin/panicwrap). This
+forks a sub-process which monitors unhandled panics. To prevent this, set
+`PanicHandler` to `func() {}` the first time you call
+`bugsnag.Configure`. This will prevent bugsnag from being able to notify you about
+unhandled panics.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    PanicHandler: func() {},
+})
+```
+
+### Synchronous
+
+Bugsnag usually starts a new goroutine before sending notifications. This means
+that notifications can be lost if you do a bugsnag.Notify and then immediately
+os.Exit. To avoid this problem, set Bugsnag to Synchronous (or just `panic()`
+instead ;).
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    Synchronous: true
+})
+```
+
+Or just for one error:
+
+```go
+bugsnag.Notify(err, bugsnag.Configuration{Synchronous: true})
+```
+
+### Transport
+
+The transport configures how Bugsnag makes http requests. By default we use
+[`http.DefaultTransport`](http://godoc.org/net/http#RoundTripper) which handles
+HTTP proxies automatically using the `$HTTP_PROXY` environment variable.
+
+```go
+bugsnag.Configure(bugsnag.Configuration{
+    Transport: http.DefaultTransport,
+})
+```
+
+## Custom data with OnBeforeNotify
+
+While it's nice that you can pass `MetaData` directly into `bugsnag.Notify`,
+`bugsnag.AutoNotify`, and `bugsnag.Recover`, this can be a bit cumbersome and
+inefficient — you're constructing the meta-data whether or not it will actually
+be used.  A better idea is to pass raw data in to these functions, and add an
+`OnBeforeNotify` filter that converts them into `MetaData`.
+
+For example, lets say our system processes jobs:
+
+```go
+type Job struct{
+    Retry     bool
+    UserId    string
+    UserEmail string
+    Name      string
+    Params    map[string]string
+}
+```
+
+You can pass a job directly into Bugsnag.notify:
+
+```go
+bugsnag.Notify(err, job)
+```
+
+And then add a filter to extract information from that job and attach it to the
+Bugsnag event:
+
+```go
+bugsnag.OnBeforeNotify(
+    func(event *bugsnag.Event, config *bugsnag.Configuration) error {
+
+        // Search all the RawData for any *Job pointers that we're passed in
+        // to bugsnag.Notify() and friends.
+        for _, datum := range event.RawData {
+            if job, ok := datum.(*Job); ok {
+                // don't notify bugsnag about errors in retries
+                if job.Retry {
+                    return fmt.Errorf("not notifying about retried jobs")
+                }
+
+                // add the job as a tab on Bugsnag.com
+                event.MetaData.AddStruct("Job", job)
+
+                // set the user correctly
+                event.User = &User{Id: job.UserId, Email: job.UserEmail}
+            }
+        }
+
+        // continue notifying as normal
+        return nil
+    })
+```
+
+## Advanced Usage
+
+If you want to have multiple different configurations around in one program,
+you can use `bugsnag.New()` to create multiple independent instances of
+Bugsnag. You can use these without calling `bugsnag.Configure()`, but bear in
+mind that until you call `bugsnag.Configure()` unhandled panics will not be
+sent to bugsnag.
+
+```go
+notifier := bugsnag.New(bugsnag.Configuration{
+    APIKey: "YOUR_OTHER_API_KEY",
+})
+```
+
+In fact any place that lets you pass in `rawData` also allows you to pass in
+configuration.  For example to send http errors to one bugsnag project, you
+could do:
+
+```go
+bugsnag.Handler(nil, bugsnag.Configuration{APIKey: "YOUR_OTHER_API_KEY"})
+```
+
+### GroupingHash
+
+If you need to override Bugsnag's grouping algorithm, you can set the
+`GroupingHash` in an `OnBeforeNotify`:
+
+```go
+bugsnag.OnBeforeNotify(
+    func (event *bugsnag.Event, config *bugsnag.Configuration) error {
+        event.GroupingHash = calculateGroupingHash(event)
+        return nil
+    })
+```
+
+### Skipping lines in stacktrace
+
+If you have your own logging wrapper all of your errors will appear to
+originate from inside it. You can avoid this problem by constructing
+an error with a stacktrace manually, and then passing that to Bugsnag.notify:
+
+```go
+import (
+    "github.com/bugsnag/bugsnag-go"
+    "github.com/bugsnag/bugsnag-go/errors"
+)
+
+func LogError(e error) {
+    // 1 removes one line of stacktrace, so the caller of LogError
+    // will be at the top.
+    e = errors.New(e, 1)
+    bugsnag.Notify(e)
+}
+```
+
diff --git a/vendor/github.com/bugsnag/bugsnag-go/appengine.go b/vendor/github.com/bugsnag/bugsnag-go/appengine.go
new file mode 100644
index 0000000000..81e25069cb
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/appengine.go
@@ -0,0 +1,81 @@
+// +build appengine
+
+package bugsnag
+
+import (
+	"appengine"
+	"appengine/urlfetch"
+	"appengine/user"
+	"fmt"
+	"log"
+	"net/http"
+)
+
+func defaultPanicHandler() {}
+
+func init() {
+	OnBeforeNotify(appengineMiddleware)
+}
+
+func appengineMiddleware(event *Event, config *Configuration) (err error) {
+	var c appengine.Context
+
+	for _, datum := range event.RawData {
+		if r, ok := datum.(*http.Request); ok {
+			c = appengine.NewContext(r)
+			break
+		} else if context, ok := datum.(appengine.Context); ok {
+			c = context
+			break
+		}
+	}
+
+	if c == nil {
+		return fmt.Errorf("No appengine context given")
+	}
+
+	// You can only use the builtin http library if you pay for appengine,
+	// so we use the appengine urlfetch service instead.
+	config.Transport = &urlfetch.Transport{
+		Context: c,
+	}
+
+	// Anything written to stderr/stdout is discarded, so lets log to the request.
+
+	if configuredLogger, ok := config.Logger.(*log.Logger); ok {
+		config.Logger = log.New(appengineWriter{c}, configuredLogger.Prefix(), configuredLogger.Flags())
+	} else {
+		config.Logger = log.New(appengineWriter{c}, log.Prefix(), log.Flags())
+	}
+
+	// Set the releaseStage appropriately
+	if config.ReleaseStage == "" {
+		if appengine.IsDevAppServer() {
+			config.ReleaseStage = "development"
+		} else {
+			config.ReleaseStage = "production"
+		}
+	}
+
+	if event.User == nil {
+		u := user.Current(c)
+		if u != nil {
+			event.User = &User{
+				Id:    u.ID,
+				Email: u.Email,
+			}
+		}
+	}
+
+	return nil
+}
+
+// Convert an appengine.Context into an io.Writer so we can create a log.Logger.
+type appengineWriter struct {
+	appengine.Context
+}
+
+func (c appengineWriter) Write(b []byte) (int, error) {
+	c.Warningf(string(b))
+	return len(b), nil
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/bugsnag.go b/vendor/github.com/bugsnag/bugsnag-go/bugsnag.go
new file mode 100644
index 0000000000..e9bbf4656a
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/bugsnag.go
@@ -0,0 +1,131 @@
+package bugsnag
+
+import (
+	"github.com/bugsnag/bugsnag-go/errors"
+	"log"
+	"net/http"
+	"os"
+	"sync"
+
+	// Fixes a bug with SHA-384 intermediate certs on some platforms.
+	// - https://github.com/bugsnag/bugsnag-go/issues/9
+	_ "crypto/sha512"
+)
+
+// The current version of bugsnag-go.
+const VERSION = "1.0.3"
+
+var once sync.Once
+var middleware middlewareStack
+
+// The configuration for the default bugsnag notifier.
+var Config Configuration
+
+var defaultNotifier = Notifier{&Config, nil}
+
+// Configure Bugsnag. The only required setting is the APIKey, which can be
+// obtained by clicking on "Settings" in your Bugsnag dashboard. This function
+// is also responsible for installing the global panic handler, so it should be
+// called as early as possible in your initialization process.
+func Configure(config Configuration) {
+	Config.update(&config)
+	once.Do(Config.PanicHandler)
+}
+
+// Notify sends an error to Bugsnag along with the current stack trace. The
+// rawData is used to send extra information along with the error. For example
+// you can pass the current http.Request to Bugsnag to see information about it
+// in the dashboard, or set the severity of the notification.
+func Notify(err error, rawData ...interface{}) error {
+	return defaultNotifier.Notify(errors.New(err, 1), rawData...)
+}
+
+// AutoNotify logs a panic on a goroutine and then repanics.
+// It should only be used in places that have existing panic handlers further
+// up the stack. See bugsnag.Recover().  The rawData is used to send extra
+// information along with any panics that are handled this way.
+// Usage: defer bugsnag.AutoNotify()
+func AutoNotify(rawData ...interface{}) {
+	if err := recover(); err != nil {
+		rawData = defaultNotifier.addDefaultSeverity(rawData, SeverityError)
+		defaultNotifier.Notify(errors.New(err, 2), rawData...)
+		panic(err)
+	}
+}
+
+// Recover logs a panic on a goroutine and then recovers.
+// The rawData is used to send extra information along with
+// any panics that are handled this way
+// Usage: defer bugsnag.Recover()
+func Recover(rawData ...interface{}) {
+	if err := recover(); err != nil {
+		rawData = defaultNotifier.addDefaultSeverity(rawData, SeverityWarning)
+		defaultNotifier.Notify(errors.New(err, 2), rawData...)
+	}
+}
+
+// OnBeforeNotify adds a callback to be run before a notification is sent to
+// Bugsnag.  It can be used to modify the event or its MetaData. Changes made
+// to the configuration are local to notifying about this event. To prevent the
+// event from being sent to Bugsnag return an error, this error will be
+// returned from bugsnag.Notify() and the event will not be sent.
+func OnBeforeNotify(callback func(event *Event, config *Configuration) error) {
+	middleware.OnBeforeNotify(callback)
+}
+
+// Handler creates an http Handler that notifies Bugsnag any panics that
+// happen. It then repanics so that the default http Server panic handler can
+// handle the panic too. The rawData is used to send extra information along
+// with any panics that are handled this way.
+func Handler(h http.Handler, rawData ...interface{}) http.Handler {
+	notifier := New(rawData...)
+	if h == nil {
+		h = http.DefaultServeMux
+	}
+
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		defer notifier.AutoNotify(r)
+		h.ServeHTTP(w, r)
+	})
+}
+
+// HandlerFunc creates an http HandlerFunc that notifies Bugsnag about any
+// panics that happen. It then repanics so that the default http Server panic
+// handler can handle the panic too. The rawData is used to send extra
+// information along with any panics that are handled this way. If you have
+// already wrapped your http server using bugsnag.Handler() you don't also need
+// to wrap each HandlerFunc.
+func HandlerFunc(h http.HandlerFunc, rawData ...interface{}) http.HandlerFunc {
+	notifier := New(rawData...)
+
+	return func(w http.ResponseWriter, r *http.Request) {
+		defer notifier.AutoNotify(r)
+		h(w, r)
+	}
+}
+
+func init() {
+	// Set up builtin middlewarez
+	OnBeforeNotify(httpRequestMiddleware)
+
+	// Default configuration
+	Config.update(&Configuration{
+		APIKey:        "",
+		Endpoint:      "https://notify.bugsnag.com/",
+		Hostname:      "",
+		AppVersion:    "",
+		ReleaseStage:  "",
+		ParamsFilters: []string{"password", "secret"},
+		// * for app-engine
+		ProjectPackages:     []string{"main*"},
+		NotifyReleaseStages: nil,
+		Logger:              log.New(os.Stdout, log.Prefix(), log.Flags()),
+		PanicHandler:        defaultPanicHandler,
+		Transport:           http.DefaultTransport,
+	})
+
+	hostname, err := os.Hostname()
+	if err == nil {
+		Config.Hostname = hostname
+	}
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/configuration.go b/vendor/github.com/bugsnag/bugsnag-go/configuration.go
new file mode 100644
index 0000000000..ad1d42db9c
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/configuration.go
@@ -0,0 +1,169 @@
+package bugsnag
+
+import (
+	"log"
+	"net/http"
+	"path/filepath"
+	"strings"
+)
+
+// Configuration sets up and customizes communication with the Bugsnag API.
+type Configuration struct {
+	// Your Bugsnag API key, e.g. "c9d60ae4c7e70c4b6c4ebd3e8056d2b8". You can
+	// find this by clicking Settings on https://bugsnag.com/.
+	APIKey string
+	// The Endpoint to notify about crashes. This defaults to
+	// "https://notify.bugsnag.com/", if you're using Bugsnag Enterprise then
+	// set it to your internal Bugsnag endpoint.
+	Endpoint string
+
+	// The current release stage. This defaults to "production" and is used to
+	// filter errors in the Bugsnag dashboard.
+	ReleaseStage string
+	// The currently running version of the app. This is used to filter errors
+	// in the Bugsnag dasboard. If you set this then Bugsnag will only re-open
+	// resolved errors if they happen in different app versions.
+	AppVersion string
+	// The hostname of the current server. This defaults to the return value of
+	// os.Hostname() and is graphed in the Bugsnag dashboard.
+	Hostname string
+
+	// The Release stages to notify in. If you set this then bugsnag-go will
+	// only send notifications to Bugsnag if the ReleaseStage is listed here.
+	NotifyReleaseStages []string
+
+	// packages that are part of your app. Bugsnag uses this to determine how
+	// to group errors and how to display them on your dashboard. You should
+	// include any packages that are part of your app, and exclude libraries
+	// and helpers. You can list wildcards here, and they'll be expanded using
+	// filepath.Glob. The default value is []string{"main*"}
+	ProjectPackages []string
+
+	// Any meta-data that matches these filters will be marked as [REDACTED]
+	// before sending a Notification to Bugsnag. It defaults to
+	// []string{"password", "secret"} so that request parameters like password,
+	// password_confirmation and auth_secret will not be sent to Bugsnag.
+	ParamsFilters []string
+
+	// The PanicHandler is used by Bugsnag to catch unhandled panics in your
+	// application. The default panicHandler uses mitchellh's panicwrap library,
+	// and you can disable this feature by passing an empty: func() {}
+	PanicHandler func()
+
+	// The logger that Bugsnag should log to. Uses the same defaults as go's
+	// builtin logging package. bugsnag-go logs whenever it notifies Bugsnag
+	// of an error, and when any error occurs inside the library itself.
+	Logger interface {
+		Printf(format string, v ...interface{}) // limited to the functions used
+	}
+	// The http Transport to use, defaults to the default http Transport. This
+	// can be configured if you are in an environment like Google App Engine
+	// that has stringent conditions on making http requests.
+	Transport http.RoundTripper
+	// Whether bugsnag should notify synchronously. This defaults to false which
+	// causes bugsnag-go to spawn a new goroutine for each notification.
+	Synchronous bool
+	// TODO: remember to update the update() function when modifying this struct
+}
+
+func (config *Configuration) update(other *Configuration) *Configuration {
+	if other.APIKey != "" {
+		config.APIKey = other.APIKey
+	}
+	if other.Endpoint != "" {
+		config.Endpoint = other.Endpoint
+	}
+	if other.Hostname != "" {
+		config.Hostname = other.Hostname
+	}
+	if other.AppVersion != "" {
+		config.AppVersion = other.AppVersion
+	}
+	if other.ReleaseStage != "" {
+		config.ReleaseStage = other.ReleaseStage
+	}
+	if other.ParamsFilters != nil {
+		config.ParamsFilters = other.ParamsFilters
+	}
+	if other.ProjectPackages != nil {
+		config.ProjectPackages = other.ProjectPackages
+	}
+	if other.Logger != nil {
+		config.Logger = other.Logger
+	}
+	if other.NotifyReleaseStages != nil {
+		config.NotifyReleaseStages = other.NotifyReleaseStages
+	}
+	if other.PanicHandler != nil {
+		config.PanicHandler = other.PanicHandler
+	}
+	if other.Transport != nil {
+		config.Transport = other.Transport
+	}
+	if other.Synchronous {
+		config.Synchronous = true
+	}
+
+	return config
+}
+
+func (config *Configuration) merge(other *Configuration) *Configuration {
+	return config.clone().update(other)
+}
+
+func (config *Configuration) clone() *Configuration {
+	clone := *config
+	return &clone
+}
+
+func (config *Configuration) isProjectPackage(pkg string) bool {
+	for _, p := range config.ProjectPackages {
+		if d, f := filepath.Split(p); f == "**" {
+			if strings.HasPrefix(pkg, d) {
+				return true
+			}
+		}
+
+		if match, _ := filepath.Match(p, pkg); match {
+			return true
+		}
+	}
+	return false
+}
+
+func (config *Configuration) stripProjectPackages(file string) string {
+	for _, p := range config.ProjectPackages {
+		if len(p) > 2 && p[len(p)-2] == '/' && p[len(p)-1] == '*' {
+			p = p[:len(p)-1]
+		} else if p[len(p)-1] == '*' && p[len(p)-2] == '*' {
+			p = p[:len(p)-2]
+		} else {
+			p = p + "/"
+		}
+		if strings.HasPrefix(file, p) {
+			return strings.TrimPrefix(file, p)
+		}
+	}
+
+	return file
+}
+
+func (config *Configuration) logf(fmt string, args ...interface{}) {
+	if config != nil && config.Logger != nil {
+		config.Logger.Printf(fmt, args...)
+	} else {
+		log.Printf(fmt, args...)
+	}
+}
+
+func (config *Configuration) notifyInReleaseStage() bool {
+	if config.NotifyReleaseStages == nil {
+		return true
+	}
+	for _, r := range config.NotifyReleaseStages {
+		if r == config.ReleaseStage {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/doc.go b/vendor/github.com/bugsnag/bugsnag-go/doc.go
new file mode 100644
index 0000000000..827e03b8be
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/doc.go
@@ -0,0 +1,69 @@
+/*
+Package bugsnag captures errors in real-time and reports them to Bugsnag (http://bugsnag.com).
+
+Using bugsnag-go is a three-step process.
+
+1. As early as possible in your program configure the notifier with your APIKey. This sets up
+handling of panics that would otherwise crash your app.
+
+	func init() {
+		bugsnag.Configure(bugsnag.Configuration{
+			APIKey: "YOUR_API_KEY_HERE",
+		})
+	}
+
+2. Add bugsnag to places that already catch panics. For example you should add it to the HTTP server
+when you call ListenAndServer:
+
+	http.ListenAndServe(":8080", bugsnag.Handler(nil))
+
+If that's not possible, for example because you're using Google App Engine, you can also wrap each
+HTTP handler manually:
+
+	http.HandleFunc("/" bugsnag.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
+		...
+	})
+
+3. To notify Bugsnag of an error that is not a panic, pass it to bugsnag.Notify. This will also
+log the error message using the configured Logger.
+
+	if err != nil {
+		bugsnag.Notify(err)
+	}
+
+For detailed integration instructions see https://bugsnag.com/docs/notifiers/go.
+
+Configuration
+
+The only required configuration is the Bugsnag API key which can be obtained by clicking "Settings"
+on the top of https://bugsnag.com/ after signing up. We also recommend you set the ReleaseStage
+and AppVersion if these make sense for your deployment workflow.
+
+RawData
+
+If you need to attach extra data to Bugsnag notifications you can do that using
+the rawData mechanism.  Most of the functions that send errors to Bugsnag allow
+you to pass in any number of interface{} values as rawData. The rawData can
+consist of the Severity, Context, User or MetaData types listed below, and
+there is also builtin support for *http.Requests.
+
+	bugsnag.Notify(err, bugsnag.SeverityError)
+
+If you want to add custom tabs to your bugsnag dashboard you can pass any value in as rawData,
+and then process it into the event's metadata using a bugsnag.OnBeforeNotify() hook.
+
+	bugsnag.Notify(err, account)
+
+	bugsnag.OnBeforeNotify(func (e *bugsnag.Event, c *bugsnag.Configuration) {
+		for datum := range e.RawData {
+			if account, ok := datum.(Account); ok {
+				e.MetaData.Add("account", "name", account.Name)
+				e.MetaData.Add("account", "url", account.URL)
+			}
+		}
+	})
+
+If necessary you can pass Configuration in as rawData, or modify the Configuration object passed
+into OnBeforeNotify hooks. Configuration passed in this way only affects the current notification.
+*/
+package bugsnag
diff --git a/vendor/github.com/bugsnag/bugsnag-go/errors/README.md b/vendor/github.com/bugsnag/bugsnag-go/errors/README.md
new file mode 100644
index 0000000000..8d8e097aa7
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/errors/README.md
@@ -0,0 +1,6 @@
+Adds stacktraces to errors in golang.
+
+This was made to help build the Bugsnag notifier but can be used standalone if
+you like to have stacktraces on errors.
+
+See [Godoc](https://godoc.org/github.com/bugsnag/bugsnag-go/errors) for the API docs.
diff --git a/vendor/github.com/bugsnag/bugsnag-go/errors/error.go b/vendor/github.com/bugsnag/bugsnag-go/errors/error.go
new file mode 100644
index 0000000000..0081c0a80c
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/errors/error.go
@@ -0,0 +1,90 @@
+// Package errors provides errors that have stack-traces.
+package errors
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"runtime"
+)
+
+// The maximum number of stackframes on any error.
+var MaxStackDepth = 50
+
+// Error is an error with an attached stacktrace. It can be used
+// wherever the builtin error interface is expected.
+type Error struct {
+	Err    error
+	stack  []uintptr
+	frames []StackFrame
+}
+
+// New makes an Error from the given value. If that value is already an
+// error then it will be used directly, if not, it will be passed to
+// fmt.Errorf("%v"). The skip parameter indicates how far up the stack
+// to start the stacktrace. 0 is from the current call, 1 from its caller, etc.
+func New(e interface{}, skip int) *Error {
+	var err error
+
+	switch e := e.(type) {
+	case *Error:
+		return e
+	case error:
+		err = e
+	default:
+		err = fmt.Errorf("%v", e)
+	}
+
+	stack := make([]uintptr, MaxStackDepth)
+	length := runtime.Callers(2+skip, stack[:])
+	return &Error{
+		Err:   err,
+		stack: stack[:length],
+	}
+}
+
+// Errorf creates a new error with the given message. You can use it
+// as a drop-in replacement for fmt.Errorf() to provide descriptive
+// errors in return values.
+func Errorf(format string, a ...interface{}) *Error {
+	return New(fmt.Errorf(format, a...), 1)
+}
+
+// Error returns the underlying error's message.
+func (err *Error) Error() string {
+	return err.Err.Error()
+}
+
+// Stack returns the callstack formatted the same way that go does
+// in runtime/debug.Stack()
+func (err *Error) Stack() []byte {
+	buf := bytes.Buffer{}
+
+	for _, frame := range err.StackFrames() {
+		buf.WriteString(frame.String())
+	}
+
+	return buf.Bytes()
+}
+
+// StackFrames returns an array of frames containing information about the
+// stack.
+func (err *Error) StackFrames() []StackFrame {
+	if err.frames == nil {
+		err.frames = make([]StackFrame, len(err.stack))
+
+		for i, pc := range err.stack {
+			err.frames[i] = NewStackFrame(pc)
+		}
+	}
+
+	return err.frames
+}
+
+// TypeName returns the type this error. e.g. *errors.stringError.
+func (err *Error) TypeName() string {
+	if _, ok := err.Err.(uncaughtPanic); ok {
+		return "panic"
+	}
+	return reflect.TypeOf(err.Err).String()
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/errors/parse_panic.go b/vendor/github.com/bugsnag/bugsnag-go/errors/parse_panic.go
new file mode 100644
index 0000000000..cc37052d78
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/errors/parse_panic.go
@@ -0,0 +1,127 @@
+package errors
+
+import (
+	"strconv"
+	"strings"
+)
+
+type uncaughtPanic struct{ message string }
+
+func (p uncaughtPanic) Error() string {
+	return p.message
+}
+
+// ParsePanic allows you to get an error object from the output of a go program
+// that panicked. This is particularly useful with https://github.com/mitchellh/panicwrap.
+func ParsePanic(text string) (*Error, error) {
+	lines := strings.Split(text, "\n")
+
+	state := "start"
+
+	var message string
+	var stack []StackFrame
+
+	for i := 0; i < len(lines); i++ {
+		line := lines[i]
+
+		if state == "start" {
+			if strings.HasPrefix(line, "panic: ") {
+				message = strings.TrimPrefix(line, "panic: ")
+				state = "seek"
+			} else {
+				return nil, Errorf("bugsnag.panicParser: Invalid line (no prefix): %s", line)
+			}
+
+		} else if state == "seek" {
+			if strings.HasPrefix(line, "goroutine ") && strings.HasSuffix(line, "[running]:") {
+				state = "parsing"
+			}
+
+		} else if state == "parsing" {
+			if line == "" {
+				state = "done"
+				break
+			}
+			createdBy := false
+			if strings.HasPrefix(line, "created by ") {
+				line = strings.TrimPrefix(line, "created by ")
+				createdBy = true
+			}
+
+			i++
+
+			if i >= len(lines) {
+				return nil, Errorf("bugsnag.panicParser: Invalid line (unpaired): %s", line)
+			}
+
+			frame, err := parsePanicFrame(line, lines[i], createdBy)
+			if err != nil {
+				return nil, err
+			}
+
+			stack = append(stack, *frame)
+			if createdBy {
+				state = "done"
+				break
+			}
+		}
+	}
+
+	if state == "done" || state == "parsing" {
+		return &Error{Err: uncaughtPanic{message}, frames: stack}, nil
+	}
+	return nil, Errorf("could not parse panic: %v", text)
+}
+
+// The lines we're passing look like this:
+//
+//     main.(*foo).destruct(0xc208067e98)
+//             /0/go/src/github.com/bugsnag/bugsnag-go/pan/main.go:22 +0x151
+func parsePanicFrame(name string, line string, createdBy bool) (*StackFrame, error) {
+	idx := strings.LastIndex(name, "(")
+	if idx == -1 && !createdBy {
+		return nil, Errorf("bugsnag.panicParser: Invalid line (no call): %s", name)
+	}
+	if idx != -1 {
+		name = name[:idx]
+	}
+	pkg := ""
+
+	if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 {
+		pkg += name[:lastslash] + "/"
+		name = name[lastslash+1:]
+	}
+	if period := strings.Index(name, "."); period >= 0 {
+		pkg += name[:period]
+		name = name[period+1:]
+	}
+
+	name = strings.Replace(name, "·", ".", -1)
+
+	if !strings.HasPrefix(line, "\t") {
+		return nil, Errorf("bugsnag.panicParser: Invalid line (no tab): %s", line)
+	}
+
+	idx = strings.LastIndex(line, ":")
+	if idx == -1 {
+		return nil, Errorf("bugsnag.panicParser: Invalid line (no line number): %s", line)
+	}
+	file := line[1:idx]
+
+	number := line[idx+1:]
+	if idx = strings.Index(number, " +"); idx > -1 {
+		number = number[:idx]
+	}
+
+	lno, err := strconv.ParseInt(number, 10, 32)
+	if err != nil {
+		return nil, Errorf("bugsnag.panicParser: Invalid line (bad line number): %s", line)
+	}
+
+	return &StackFrame{
+		File:       file,
+		LineNumber: int(lno),
+		Package:    pkg,
+		Name:       name,
+	}, nil
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/errors/stackframe.go b/vendor/github.com/bugsnag/bugsnag-go/errors/stackframe.go
new file mode 100644
index 0000000000..4edadbc589
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/errors/stackframe.go
@@ -0,0 +1,97 @@
+package errors
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"runtime"
+	"strings"
+)
+
+// A StackFrame contains all necessary information about to generate a line
+// in a callstack.
+type StackFrame struct {
+	File           string
+	LineNumber     int
+	Name           string
+	Package        string
+	ProgramCounter uintptr
+}
+
+// NewStackFrame popoulates a stack frame object from the program counter.
+func NewStackFrame(pc uintptr) (frame StackFrame) {
+
+	frame = StackFrame{ProgramCounter: pc}
+	if frame.Func() == nil {
+		return
+	}
+	frame.Package, frame.Name = packageAndName(frame.Func())
+
+	// pc -1 because the program counters we use are usually return addresses,
+	// and we want to show the line that corresponds to the function call
+	frame.File, frame.LineNumber = frame.Func().FileLine(pc - 1)
+	return
+
+}
+
+// Func returns the function that this stackframe corresponds to
+func (frame *StackFrame) Func() *runtime.Func {
+	if frame.ProgramCounter == 0 {
+		return nil
+	}
+	return runtime.FuncForPC(frame.ProgramCounter)
+}
+
+// String returns the stackframe formatted in the same way as go does
+// in runtime/debug.Stack()
+func (frame *StackFrame) String() string {
+	str := fmt.Sprintf("%s:%d (0x%x)\n", frame.File, frame.LineNumber, frame.ProgramCounter)
+
+	source, err := frame.SourceLine()
+	if err != nil {
+		return str
+	}
+
+	return str + fmt.Sprintf("\t%s: %s\n", frame.Name, source)
+}
+
+// SourceLine gets the line of code (from File and Line) of the original source if possible
+func (frame *StackFrame) SourceLine() (string, error) {
+	data, err := ioutil.ReadFile(frame.File)
+
+	if err != nil {
+		return "", err
+	}
+
+	lines := bytes.Split(data, []byte{'\n'})
+	if frame.LineNumber <= 0 || frame.LineNumber >= len(lines) {
+		return "???", nil
+	}
+	// -1 because line-numbers are 1 based, but our array is 0 based
+	return string(bytes.Trim(lines[frame.LineNumber-1], " \t")), nil
+}
+
+func packageAndName(fn *runtime.Func) (string, string) {
+	name := fn.Name()
+	pkg := ""
+
+	// The name includes the path name to the package, which is unnecessary
+	// since the file name is already included.  Plus, it has center dots.
+	// That is, we see
+	//  runtime/debug.*T·ptrmethod
+	// and want
+	//  *T.ptrmethod
+	// Since the package path might contains dots (e.g. code.google.com/...),
+	// we first remove the path prefix if there is one.
+	if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 {
+		pkg += name[:lastslash] + "/"
+		name = name[lastslash+1:]
+	}
+	if period := strings.Index(name, "."); period >= 0 {
+		pkg += name[:period]
+		name = name[period+1:]
+	}
+
+	name = strings.Replace(name, "·", ".", -1)
+	return pkg, name
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/event.go b/vendor/github.com/bugsnag/bugsnag-go/event.go
new file mode 100644
index 0000000000..320c6154c3
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/event.go
@@ -0,0 +1,143 @@
+package bugsnag
+
+import (
+	"strings"
+
+	"github.com/bugsnag/bugsnag-go/errors"
+)
+
+// Context is the context of the error in Bugsnag.
+// This can be passed to Notify, Recover or AutoNotify as rawData.
+type Context struct {
+	String string
+}
+
+// User represents the searchable user-data on Bugsnag. The Id is also used
+// to determine the number of users affected by a bug. This can be
+// passed to Notify, Recover or AutoNotify as rawData.
+type User struct {
+	Id    string `json:"id,omitempty"`
+	Name  string `json:"name,omitempty"`
+	Email string `json:"email,omitempty"`
+}
+
+// ErrorClass overrides the error class in Bugsnag.
+// This struct enables you to group errors as you like.
+type ErrorClass struct {
+	Name string
+}
+
+// Sets the severity of the error on Bugsnag. These values can be
+// passed to Notify, Recover or AutoNotify as rawData.
+var (
+	SeverityError   = severity{"error"}
+	SeverityWarning = severity{"warning"}
+	SeverityInfo    = severity{"info"}
+)
+
+// The severity tag type, private so that people can only use Error,Warning,Info
+type severity struct {
+	String string
+}
+
+// The form of stacktrace that Bugsnag expects
+type stackFrame struct {
+	Method     string `json:"method"`
+	File       string `json:"file"`
+	LineNumber int    `json:"lineNumber"`
+	InProject  bool   `json:"inProject,omitempty"`
+}
+
+// Event represents a payload of data that gets sent to Bugsnag.
+// This is passed to each OnBeforeNotify hook.
+type Event struct {
+
+	// The original error that caused this event, not sent to Bugsnag.
+	Error *errors.Error
+
+	// The rawData affecting this error, not sent to Bugsnag.
+	RawData []interface{}
+
+	// The error class to be sent to Bugsnag. This defaults to the type name of the Error, for
+	// example *error.String
+	ErrorClass string
+	// The error message to be sent to Bugsnag. This defaults to the return value of Error.Error()
+	Message string
+	// The stacktrrace of the error to be sent to Bugsnag.
+	Stacktrace []stackFrame
+
+	// The context to be sent to Bugsnag. This should be set to the part of the app that was running,
+	// e.g. for http requests, set it to the path.
+	Context string
+	// The severity of the error. Can be SeverityError, SeverityWarning or SeverityInfo.
+	Severity severity
+	// The grouping hash is used to override Bugsnag's grouping. Set this if you'd like all errors with
+	// the same grouping hash to group together in the dashboard.
+	GroupingHash string
+
+	// User data to send to Bugsnag. This is searchable on the dashboard.
+	User *User
+	// Other MetaData to send to Bugsnag. Appears as a set of tabbed tables in the dashboard.
+	MetaData MetaData
+}
+
+func newEvent(err *errors.Error, rawData []interface{}, notifier *Notifier) (*Event, *Configuration) {
+
+	config := notifier.Config
+	event := &Event{
+		Error:   err,
+		RawData: append(notifier.RawData, rawData...),
+
+		ErrorClass: err.TypeName(),
+		Message:    err.Error(),
+		Stacktrace: make([]stackFrame, len(err.StackFrames())),
+
+		Severity: SeverityWarning,
+
+		MetaData: make(MetaData),
+	}
+
+	for _, datum := range event.RawData {
+		switch datum := datum.(type) {
+		case severity:
+			event.Severity = datum
+
+		case Context:
+			event.Context = datum.String
+
+		case Configuration:
+			config = config.merge(&datum)
+
+		case MetaData:
+			event.MetaData.Update(datum)
+
+		case User:
+			event.User = &datum
+
+		case ErrorClass:
+			event.ErrorClass = datum.Name
+		}
+	}
+
+	for i, frame := range err.StackFrames() {
+		file := frame.File
+		inProject := config.isProjectPackage(frame.Package)
+
+		// remove $GOROOT and $GOHOME from other frames
+		if idx := strings.Index(file, frame.Package); idx > -1 {
+			file = file[idx:]
+		}
+		if inProject {
+			file = config.stripProjectPackages(file)
+		}
+
+		event.Stacktrace[i] = stackFrame{
+			Method:     frame.Name,
+			File:       file,
+			LineNumber: frame.LineNumber,
+			InProject:  inProject,
+		}
+	}
+
+	return event, config
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/README.md b/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/README.md
new file mode 100644
index 0000000000..1ac49148f5
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/README.md
@@ -0,0 +1,10 @@
+This is an example google app-engine app.
+
+To use it you will need to install the [App Engine
+SDK](https://cloud.google.com/appengine/downloads) for Go.
+
+Then run:
+
+    goapp deploy
+
+Then open: https://bugsnag-test.appspot.com/ in your web-browser.
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/app.yaml b/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/app.yaml
new file mode 100644
index 0000000000..2fdff7b533
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/app.yaml
@@ -0,0 +1,8 @@
+application: bugsnag-test
+version: 1
+runtime: go
+api_version: go1
+
+handlers:
+- url: /.*
+  script: _go_app
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/hello.go b/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/hello.go
new file mode 100644
index 0000000000..a5c8bbdd45
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/hello.go
@@ -0,0 +1,30 @@
+package mellow
+
+import (
+	"fmt"
+	"net/http"
+	"os"
+
+	"github.com/bugsnag/bugsnag-go"
+)
+
+func init() {
+	bugsnag.OnBeforeNotify(func(event *bugsnag.Event, config *bugsnag.Configuration) error {
+		event.MetaData.AddStruct("original", event.Error.StackFrames())
+		return nil
+	})
+	bugsnag.Configure(bugsnag.Configuration{
+		APIKey: "066f5ad3590596f9aa8d601ea89af845",
+	})
+
+	http.HandleFunc("/", bugsnag.HandlerFunc(handler))
+}
+
+func handler(w http.ResponseWriter, r *http.Request) {
+	fmt.Fprint(w, "welcome")
+	notifier := bugsnag.New(r)
+	notifier.Notify(fmt.Errorf("oh hia"), bugsnag.MetaData{"env": {"values": os.Environ()}})
+	fmt.Fprint(w, "welcome\n")
+
+	panic("zoomg")
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/mylogs.txt b/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/mylogs.txt
new file mode 100644
index 0000000000..a9c57d5f2e
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/appengine/mylogs.txt
@@ -0,0 +1,4 @@
+2601:9:8480:11d2:7909:b2e5:3722:ef57 - - [08/Jul/2014:01:16:25 -0700] "GET / HTTP/1.1" 500 0 - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
+2601:9:8480:11d2:7909:b2e5:3722:ef57 - - [08/Jul/2014:01:16:25 -0700] "GET /favicon.ico HTTP/1.1" 500 0 - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
+2601:9:8480:11d2:7909:b2e5:3722:ef57 - - [08/Jul/2014:01:18:20 -0700] "GET / HTTP/1.1" 500 0 - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
+2601:9:8480:11d2:7909:b2e5:3722:ef57 - - [08/Jul/2014:01:18:20 -0700] "GET /favicon.ico HTTP/1.1" 500 0 - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/http/main.go b/vendor/github.com/bugsnag/bugsnag-go/examples/http/main.go
new file mode 100644
index 0000000000..d32a76a64b
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/http/main.go
@@ -0,0 +1,31 @@
+package main
+
+import (
+	"github.com/bugsnag/bugsnag-go"
+	"log"
+	"net/http"
+)
+
+func main() {
+
+	http.HandleFunc("/", Get)
+
+	bugsnag.Configure(bugsnag.Configuration{
+		APIKey: "066f5ad3590596f9aa8d601ea89af845",
+	})
+
+	log.Println("Serving on 9001")
+	http.ListenAndServe(":9001", bugsnag.Handler(nil))
+}
+
+func Get(w http.ResponseWriter, r *http.Request) {
+	w.WriteHeader(200)
+	w.Write([]byte("OK\n"))
+
+	var a struct{}
+	crash(a)
+}
+
+func crash(a interface{}) string {
+	return a.(string)
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/.gitignore b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/.gitignore
new file mode 100644
index 0000000000..dae67d0f7b
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/.gitignore
@@ -0,0 +1,3 @@
+test-results/
+tmp/
+routes/
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/controllers/app.go b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/controllers/app.go
new file mode 100644
index 0000000000..6cf8480888
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/controllers/app.go
@@ -0,0 +1,19 @@
+package controllers
+
+import "github.com/revel/revel"
+import "time"
+
+type App struct {
+	*revel.Controller
+}
+
+func (c App) Index() revel.Result {
+	go func() {
+		time.Sleep(5 * time.Second)
+		panic("hello!")
+	}()
+
+	s := make([]string, 0)
+	revel.INFO.Print(s[0])
+	return c.Render()
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/init.go b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/init.go
new file mode 100644
index 0000000000..5795414a1c
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/init.go
@@ -0,0 +1,40 @@
+package app
+
+import "github.com/revel/revel"
+import "github.com/bugsnag/bugsnag-go/revel"
+
+func init() {
+	// Filters is the default set of global filters.
+	revel.Filters = []revel.Filter{
+		revel.PanicFilter,             // Recover from panics and display an error page instead.
+		bugsnagrevel.Filter,           // Send panics to Bugsnag
+		revel.RouterFilter,            // Use the routing table to select the right Action
+		revel.FilterConfiguringFilter, // A hook for adding or removing per-Action filters.
+		revel.ParamsFilter,            // Parse parameters into Controller.Params.
+		revel.SessionFilter,           // Restore and write the session cookie.
+		revel.FlashFilter,             // Restore and write the flash cookie.
+		revel.ValidationFilter,        // Restore kept validation errors and save new ones from cookie.
+		revel.I18nFilter,              // Resolve the requested language
+		HeaderFilter,                  // Add some security based headers
+		revel.InterceptorFilter,       // Run interceptors around the action.
+		revel.CompressFilter,          // Compress the result.
+		revel.ActionInvoker,           // Invoke the action.
+	}
+
+	// register startup functions with OnAppStart
+	// ( order dependent )
+	// revel.OnAppStart(InitDB())
+	// revel.OnAppStart(FillCache())
+}
+
+// TODO turn this into revel.HeaderFilter
+// should probably also have a filter for CSRF
+// not sure if it can go in the same filter or not
+var HeaderFilter = func(c *revel.Controller, fc []revel.Filter) {
+	// Add some common security headers
+	c.Response.Out.Header().Add("X-Frame-Options", "SAMEORIGIN")
+	c.Response.Out.Header().Add("X-XSS-Protection", "1; mode=block")
+	c.Response.Out.Header().Add("X-Content-Type-Options", "nosniff")
+
+	fc[0](c, fc[1:]) // Execute the next filter stage.
+}
diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/App/Index.html b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/App/Index.html
new file mode 100644
index 0000000000..deb2304c8c
--- /dev/null
+++ b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/App/Index.html
@@ -0,0 +1,23 @@
+{{set . "title" "Home"}}
+{{template "header.html" .}}
+
+It works!
+        
+      
+ {{.Description}} +
+ {{end}} +{{end}} + + diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/errors/500.html b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/errors/500.html new file mode 100644 index 0000000000..0cef4deb4a --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/errors/500.html @@ -0,0 +1,16 @@ + + + ++ This exception has been logged. +
+ {{end}} + + diff --git a/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/flash.html b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/flash.html new file mode 100644 index 0000000000..9c9ade9692 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/examples/revelapp/app/views/flash.html @@ -0,0 +1,18 @@ +{{if .flash.success}} +