From 930b639cc9cd2d2873302f30303378c0e53816a8 Mon Sep 17 00:00:00 2001
From: Wim <wim@42.be>
Date: Sat, 18 Feb 2017 23:00:46 +0100
Subject: Update vendor

---
 vendor/github.com/GeertJohan/go.rice/LICENSE       |  22 ++
 vendor/github.com/GeertJohan/go.rice/appended.go   | 138 +++++++++
 vendor/github.com/GeertJohan/go.rice/box.go        | 337 +++++++++++++++++++++
 vendor/github.com/GeertJohan/go.rice/config.go     |  39 +++
 vendor/github.com/GeertJohan/go.rice/debug.go      |   4 +
 vendor/github.com/GeertJohan/go.rice/embedded.go   |  90 ++++++
 .../GeertJohan/go.rice/embedded/embedded.go        |  80 +++++
 .../GeertJohan/go.rice/example/example.go          |  69 +++++
 vendor/github.com/GeertJohan/go.rice/file.go       | 144 +++++++++
 vendor/github.com/GeertJohan/go.rice/http.go       |  21 ++
 .../github.com/GeertJohan/go.rice/rice/append.go   | 172 +++++++++++
 vendor/github.com/GeertJohan/go.rice/rice/clean.go |  33 ++
 .../github.com/GeertJohan/go.rice/rice/embed-go.go | 158 ++++++++++
 .../GeertJohan/go.rice/rice/embed-syso.go          | 204 +++++++++++++
 vendor/github.com/GeertJohan/go.rice/rice/find.go  | 150 +++++++++
 vendor/github.com/GeertJohan/go.rice/rice/flags.go |  80 +++++
 .../GeertJohan/go.rice/rice/identifier.go          |  14 +
 vendor/github.com/GeertJohan/go.rice/rice/main.go  |  68 +++++
 .../GeertJohan/go.rice/rice/templates.go           |  98 ++++++
 vendor/github.com/GeertJohan/go.rice/rice/util.go  |  22 ++
 .../GeertJohan/go.rice/rice/writecoff.go           |  42 +++
 vendor/github.com/GeertJohan/go.rice/sort.go       |  19 ++
 vendor/github.com/GeertJohan/go.rice/virtual.go    | 252 +++++++++++++++
 vendor/github.com/GeertJohan/go.rice/walk.go       | 122 ++++++++
 24 files changed, 2378 insertions(+)
 create mode 100644 vendor/github.com/GeertJohan/go.rice/LICENSE
 create mode 100644 vendor/github.com/GeertJohan/go.rice/appended.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/box.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/config.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/debug.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/embedded.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/embedded/embedded.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/example/example.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/file.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/http.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/append.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/clean.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/embed-go.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/embed-syso.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/find.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/flags.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/identifier.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/main.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/templates.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/util.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/rice/writecoff.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/sort.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/virtual.go
 create mode 100644 vendor/github.com/GeertJohan/go.rice/walk.go

(limited to 'vendor/github.com/GeertJohan')

diff --git a/vendor/github.com/GeertJohan/go.rice/LICENSE b/vendor/github.com/GeertJohan/go.rice/LICENSE
new file mode 100644
index 00000000..8b4409d7
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2013, Geert-Johan Riemer
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/vendor/github.com/GeertJohan/go.rice/appended.go b/vendor/github.com/GeertJohan/go.rice/appended.go
new file mode 100644
index 00000000..a986a0c5
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/appended.go
@@ -0,0 +1,138 @@
+package rice
+
+import (
+	"archive/zip"
+	"log"
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
+
+	"github.com/daaku/go.zipexe"
+	"github.com/kardianos/osext"
+)
+
+// appendedBox defines an appended box
+type appendedBox struct {
+	Name  string                   // box name
+	Files map[string]*appendedFile // appended files (*zip.File) by full path
+}
+
+type appendedFile struct {
+	zipFile  *zip.File
+	dir      bool
+	dirInfo  *appendedDirInfo
+	children []*appendedFile
+	content  []byte
+}
+
+// appendedBoxes is a public register of appendes boxes
+var appendedBoxes = make(map[string]*appendedBox)
+
+func init() {
+	// find if exec is appended
+	thisFile, err := osext.Executable()
+	if err != nil {
+		return // not appended or cant find self executable
+	}
+	closer, rd, err := zipexe.OpenCloser(thisFile)
+	if err != nil {
+		return // not appended
+	}
+	defer closer.Close()
+
+	for _, f := range rd.File {
+		// get box and file name from f.Name
+		fileParts := strings.SplitN(strings.TrimLeft(filepath.ToSlash(f.Name), "/"), "/", 2)
+		boxName := fileParts[0]
+		var fileName string
+		if len(fileParts) > 1 {
+			fileName = fileParts[1]
+		}
+
+		// find box or create new one if doesn't exist
+		box := appendedBoxes[boxName]
+		if box == nil {
+			box = &appendedBox{
+				Name:  boxName,
+				Files: make(map[string]*appendedFile),
+			}
+			appendedBoxes[boxName] = box
+		}
+
+		// create and add file to box
+		af := &appendedFile{
+			zipFile: f,
+		}
+		if f.Comment == "dir" {
+			af.dir = true
+			af.dirInfo = &appendedDirInfo{
+				name: filepath.Base(af.zipFile.Name),
+				//++ TODO: use zip modtime when that is set correctly: af.zipFile.ModTime()
+				time: time.Now(),
+			}
+		} else {
+			// this is a file, we need it's contents so we can create a bytes.Reader when the file is opened
+			// make a new byteslice
+			af.content = make([]byte, af.zipFile.FileInfo().Size())
+			// ignore reading empty files from zip (empty file still is a valid file to be read though!)
+			if len(af.content) > 0 {
+				// open io.ReadCloser
+				rc, err := af.zipFile.Open()
+				if err != nil {
+					af.content = nil // this will cause an error when the file is being opened or seeked (which is good)
+					// TODO: it's quite blunt to just log this stuff. but this is in init, so rice.Debug can't be changed yet..
+					log.Printf("error opening appended file %s: %v", af.zipFile.Name, err)
+				} else {
+					_, err = rc.Read(af.content)
+					rc.Close()
+					if err != nil {
+						af.content = nil // this will cause an error when the file is being opened or seeked (which is good)
+						// TODO: it's quite blunt to just log this stuff. but this is in init, so rice.Debug can't be changed yet..
+						log.Printf("error reading data for appended file %s: %v", af.zipFile.Name, err)
+					}
+				}
+			}
+		}
+
+		// add appendedFile to box file list
+		box.Files[fileName] = af
+
+		// add to parent dir (if any)
+		dirName := filepath.Dir(fileName)
+		if dirName == "." {
+			dirName = ""
+		}
+		if fileName != "" { // don't make box root dir a child of itself
+			if dir := box.Files[dirName]; dir != nil {
+				dir.children = append(dir.children, af)
+			}
+		}
+	}
+}
+
+// implements os.FileInfo.
+// used for Readdir()
+type appendedDirInfo struct {
+	name string
+	time time.Time
+}
+
+func (adi *appendedDirInfo) Name() string {
+	return adi.name
+}
+func (adi *appendedDirInfo) Size() int64 {
+	return 0
+}
+func (adi *appendedDirInfo) Mode() os.FileMode {
+	return os.ModeDir
+}
+func (adi *appendedDirInfo) ModTime() time.Time {
+	return adi.time
+}
+func (adi *appendedDirInfo) IsDir() bool {
+	return true
+}
+func (adi *appendedDirInfo) Sys() interface{} {
+	return nil
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/box.go b/vendor/github.com/GeertJohan/go.rice/box.go
new file mode 100644
index 00000000..71482e24
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/box.go
@@ -0,0 +1,337 @@
+package rice
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"time"
+
+	"github.com/GeertJohan/go.rice/embedded"
+)
+
+// Box abstracts a directory for resources/files.
+// It can either load files from disk, or from embedded code (when `rice --embed` was ran).
+type Box struct {
+	name         string
+	absolutePath string
+	embed        *embedded.EmbeddedBox
+	appendd      *appendedBox
+}
+
+var defaultLocateOrder = []LocateMethod{LocateEmbedded, LocateAppended, LocateFS}
+
+func findBox(name string, order []LocateMethod) (*Box, error) {
+	b := &Box{name: name}
+
+	// no support for absolute paths since gopath can be different on different machines.
+	// therefore, required box must be located relative to package requiring it.
+	if filepath.IsAbs(name) {
+		return nil, errors.New("given name/path is absolute")
+	}
+
+	var err error
+	for _, method := range order {
+		switch method {
+		case LocateEmbedded:
+			if embed := embedded.EmbeddedBoxes[name]; embed != nil {
+				b.embed = embed
+				return b, nil
+			}
+
+		case LocateAppended:
+			appendedBoxName := strings.Replace(name, `/`, `-`, -1)
+			if appendd := appendedBoxes[appendedBoxName]; appendd != nil {
+				b.appendd = appendd
+				return b, nil
+			}
+
+		case LocateFS:
+			// resolve absolute directory path
+			err := b.resolveAbsolutePathFromCaller()
+			if err != nil {
+				continue
+			}
+			// check if absolutePath exists on filesystem
+			info, err := os.Stat(b.absolutePath)
+			if err != nil {
+				continue
+			}
+			// check if absolutePath is actually a directory
+			if !info.IsDir() {
+				err = errors.New("given name/path is not a directory")
+				continue
+			}
+			return b, nil
+		case LocateWorkingDirectory:
+			// resolve absolute directory path
+			err := b.resolveAbsolutePathFromWorkingDirectory()
+			if err != nil {
+				continue
+			}
+			// check if absolutePath exists on filesystem
+			info, err := os.Stat(b.absolutePath)
+			if err != nil {
+				continue
+			}
+			// check if absolutePath is actually a directory
+			if !info.IsDir() {
+				err = errors.New("given name/path is not a directory")
+				continue
+			}
+			return b, nil
+		}
+	}
+
+	if err == nil {
+		err = fmt.Errorf("could not locate box %q", name)
+	}
+
+	return nil, err
+}
+
+// FindBox returns a Box instance for given name.
+// When the given name is a relative path, it's base path will be the calling pkg/cmd's source root.
+// When the given name is absolute, it's absolute. derp.
+// Make sure the path doesn't contain any sensitive information as it might be placed into generated go source (embedded).
+func FindBox(name string) (*Box, error) {
+	return findBox(name, defaultLocateOrder)
+}
+
+// MustFindBox returns a Box instance for given name, like FindBox does.
+// It does not return an error, instead it panics when an error occurs.
+func MustFindBox(name string) *Box {
+	box, err := findBox(name, defaultLocateOrder)
+	if err != nil {
+		panic(err)
+	}
+	return box
+}
+
+// This is injected as a mutable function literal so that we can mock it out in
+// tests and return a fixed test file.
+var resolveAbsolutePathFromCaller = func(name string, nStackFrames int) (string, error) {
+	_, callingGoFile, _, ok := runtime.Caller(nStackFrames)
+	if !ok {
+		return "", errors.New("couldn't find caller on stack")
+	}
+
+	// resolve to proper path
+	pkgDir := filepath.Dir(callingGoFile)
+	// fix for go cover
+	const coverPath = "_test/_obj_test"
+	if !filepath.IsAbs(pkgDir) {
+		if i := strings.Index(pkgDir, coverPath); i >= 0 {
+			pkgDir = pkgDir[:i] + pkgDir[i+len(coverPath):]            // remove coverPath
+			pkgDir = filepath.Join(os.Getenv("GOPATH"), "src", pkgDir) // make absolute
+		}
+	}
+	return filepath.Join(pkgDir, name), nil
+}
+
+func (b *Box) resolveAbsolutePathFromCaller() error {
+	path, err := resolveAbsolutePathFromCaller(b.name, 4)
+	if err != nil {
+		return err
+	}
+	b.absolutePath = path
+	return nil
+
+}
+
+func (b *Box) resolveAbsolutePathFromWorkingDirectory() error {
+	path, err := os.Getwd()
+	if err != nil {
+		return err
+	}
+	b.absolutePath = filepath.Join(path, b.name)
+	return nil
+}
+
+// IsEmbedded indicates wether this box was embedded into the application
+func (b *Box) IsEmbedded() bool {
+	return b.embed != nil
+}
+
+// IsAppended indicates wether this box was appended to the application
+func (b *Box) IsAppended() bool {
+	return b.appendd != nil
+}
+
+// Time returns how actual the box is.
+// When the box is embedded, it's value is saved in the embedding code.
+// When the box is live, this methods returns time.Now()
+func (b *Box) Time() time.Time {
+	if b.IsEmbedded() {
+		return b.embed.Time
+	}
+
+	//++ TODO: return time for appended box
+
+	return time.Now()
+}
+
+// Open opens a File from the box
+// If there is an error, it will be of type *os.PathError.
+func (b *Box) Open(name string) (*File, error) {
+	if Debug {
+		fmt.Printf("Open(%s)\n", name)
+	}
+
+	if b.IsEmbedded() {
+		if Debug {
+			fmt.Println("Box is embedded")
+		}
+
+		// trim prefix (paths are relative to box)
+		name = strings.TrimLeft(name, "/")
+		if Debug {
+			fmt.Printf("Trying %s\n", name)
+		}
+
+		// search for file
+		ef := b.embed.Files[name]
+		if ef == nil {
+			if Debug {
+				fmt.Println("Didn't find file in embed")
+			}
+			// file not found, try dir
+			ed := b.embed.Dirs[name]
+			if ed == nil {
+				if Debug {
+					fmt.Println("Didn't find dir in embed")
+				}
+				// dir not found, error out
+				return nil, &os.PathError{
+					Op:   "open",
+					Path: name,
+					Err:  os.ErrNotExist,
+				}
+			}
+			if Debug {
+				fmt.Println("Found dir. Returning virtual dir")
+			}
+			vd := newVirtualDir(ed)
+			return &File{virtualD: vd}, nil
+		}
+
+		// box is embedded
+		if Debug {
+			fmt.Println("Found file. Returning virtual file")
+		}
+		vf := newVirtualFile(ef)
+		return &File{virtualF: vf}, nil
+	}
+
+	if b.IsAppended() {
+		// trim prefix (paths are relative to box)
+		name = strings.TrimLeft(name, "/")
+
+		// search for file
+		appendedFile := b.appendd.Files[name]
+		if appendedFile == nil {
+			return nil, &os.PathError{
+				Op:   "open",
+				Path: name,
+				Err:  os.ErrNotExist,
+			}
+		}
+
+		// create new file
+		f := &File{
+			appendedF: appendedFile,
+		}
+
+		// if this file is a directory, we want to be able to read and seek
+		if !appendedFile.dir {
+			// looks like malformed data in zip, error now
+			if appendedFile.content == nil {
+				return nil, &os.PathError{
+					Op:   "open",
+					Path: "name",
+					Err:  errors.New("error reading data from zip file"),
+				}
+			}
+			// create new bytes.Reader
+			f.appendedFileReader = bytes.NewReader(appendedFile.content)
+		}
+
+		// all done
+		return f, nil
+	}
+
+	// perform os open
+	if Debug {
+		fmt.Printf("Using os.Open(%s)", filepath.Join(b.absolutePath, name))
+	}
+	file, err := os.Open(filepath.Join(b.absolutePath, name))
+	if err != nil {
+		return nil, err
+	}
+	return &File{realF: file}, nil
+}
+
+// Bytes returns the content of the file with given name as []byte.
+func (b *Box) Bytes(name string) ([]byte, error) {
+	file, err := b.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	defer file.Close()
+
+	content, err := ioutil.ReadAll(file)
+	if err != nil {
+		return nil, err
+	}
+
+	return content, nil
+}
+
+// MustBytes returns the content of the file with given name as []byte.
+// panic's on error.
+func (b *Box) MustBytes(name string) []byte {
+	bts, err := b.Bytes(name)
+	if err != nil {
+		panic(err)
+	}
+	return bts
+}
+
+// String returns the content of the file with given name as string.
+func (b *Box) String(name string) (string, error) {
+	// check if box is embedded, optimized fast path
+	if b.IsEmbedded() {
+		// find file in embed
+		ef := b.embed.Files[name]
+		if ef == nil {
+			return "", os.ErrNotExist
+		}
+		// return as string
+		return ef.Content, nil
+	}
+
+	bts, err := b.Bytes(name)
+	if err != nil {
+		return "", err
+	}
+	return string(bts), nil
+}
+
+// MustString returns the content of the file with given name as string.
+// panic's on error.
+func (b *Box) MustString(name string) string {
+	str, err := b.String(name)
+	if err != nil {
+		panic(err)
+	}
+	return str
+}
+
+// Name returns the name of the box
+func (b *Box) Name() string {
+	return b.name
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/config.go b/vendor/github.com/GeertJohan/go.rice/config.go
new file mode 100644
index 00000000..45eb398f
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/config.go
@@ -0,0 +1,39 @@
+package rice
+
+// LocateMethod defines how a box is located.
+type LocateMethod int
+
+const (
+	LocateFS               = LocateMethod(iota) // Locate on the filesystem according to package path.
+	LocateAppended                              // Locate boxes appended to the executable.
+	LocateEmbedded                              // Locate embedded boxes.
+	LocateWorkingDirectory                      // Locate on the binary working directory
+)
+
+// Config allows customizing the box lookup behavior.
+type Config struct {
+	// LocateOrder defines the priority order that boxes are searched for. By
+	// default, the package global FindBox searches for embedded boxes first,
+	// then appended boxes, and then finally boxes on the filesystem.  That
+	// search order may be customized by provided the ordered list here. Leaving
+	// out a particular method will omit that from the search space. For
+	// example, []LocateMethod{LocateEmbedded, LocateAppended} will never search
+	// the filesystem for boxes.
+	LocateOrder []LocateMethod
+}
+
+// FindBox searches for boxes using the LocateOrder of the config.
+func (c *Config) FindBox(boxName string) (*Box, error) {
+	return findBox(boxName, c.LocateOrder)
+}
+
+// MustFindBox searches for boxes using the LocateOrder of the config, like
+// FindBox does.  It does not return an error, instead it panics when an error
+// occurs.
+func (c *Config) MustFindBox(boxName string) *Box {
+	box, err := findBox(boxName, c.LocateOrder)
+	if err != nil {
+		panic(err)
+	}
+	return box
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/debug.go b/vendor/github.com/GeertJohan/go.rice/debug.go
new file mode 100644
index 00000000..2e68c842
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/debug.go
@@ -0,0 +1,4 @@
+package rice
+
+// Debug can be set to true to enable debugging.
+var Debug = false
diff --git a/vendor/github.com/GeertJohan/go.rice/embedded.go b/vendor/github.com/GeertJohan/go.rice/embedded.go
new file mode 100644
index 00000000..4f03fe1f
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/embedded.go
@@ -0,0 +1,90 @@
+package rice
+
+import (
+	"os"
+	"time"
+
+	"github.com/GeertJohan/go.rice/embedded"
+)
+
+// re-type to make exported methods invisible to user (godoc)
+// they're not required for the user
+// embeddedDirInfo implements os.FileInfo
+type embeddedDirInfo embedded.EmbeddedDir
+
+// Name returns the base name of the directory
+// (implementing os.FileInfo)
+func (ed *embeddedDirInfo) Name() string {
+	return ed.Filename
+}
+
+// Size always returns 0
+// (implementing os.FileInfo)
+func (ed *embeddedDirInfo) Size() int64 {
+	return 0
+}
+
+// Mode returns the file mode bits
+// (implementing os.FileInfo)
+func (ed *embeddedDirInfo) Mode() os.FileMode {
+	return os.FileMode(0555 | os.ModeDir) // dr-xr-xr-x
+}
+
+// ModTime returns the modification time
+// (implementing os.FileInfo)
+func (ed *embeddedDirInfo) ModTime() time.Time {
+	return ed.DirModTime
+}
+
+// IsDir returns the abbreviation for Mode().IsDir() (always true)
+// (implementing os.FileInfo)
+func (ed *embeddedDirInfo) IsDir() bool {
+	return true
+}
+
+// Sys returns the underlying data source (always nil)
+// (implementing os.FileInfo)
+func (ed *embeddedDirInfo) Sys() interface{} {
+	return nil
+}
+
+// re-type to make exported methods invisible to user (godoc)
+// they're not required for the user
+// embeddedFileInfo implements os.FileInfo
+type embeddedFileInfo embedded.EmbeddedFile
+
+// Name returns the base name of the file
+// (implementing os.FileInfo)
+func (ef *embeddedFileInfo) Name() string {
+	return ef.Filename
+}
+
+// Size returns the length in bytes for regular files; system-dependent for others
+// (implementing os.FileInfo)
+func (ef *embeddedFileInfo) Size() int64 {
+	return int64(len(ef.Content))
+}
+
+// Mode returns the file mode bits
+// (implementing os.FileInfo)
+func (ef *embeddedFileInfo) Mode() os.FileMode {
+	return os.FileMode(0555) // r-xr-xr-x
+}
+
+// ModTime returns the modification time
+// (implementing os.FileInfo)
+func (ef *embeddedFileInfo) ModTime() time.Time {
+	return ef.FileModTime
+}
+
+// IsDir returns the abbreviation for Mode().IsDir() (always false)
+// (implementing os.FileInfo)
+func (ef *embeddedFileInfo) IsDir() bool {
+	return false
+}
+
+// Sys returns the underlying data source (always nil)
+// (implementing os.FileInfo)
+func (ef *embeddedFileInfo) Sys() interface{} {
+	return nil
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/embedded/embedded.go b/vendor/github.com/GeertJohan/go.rice/embedded/embedded.go
new file mode 100644
index 00000000..bba8e588
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/embedded/embedded.go
@@ -0,0 +1,80 @@
+// Package embedded defines embedded data types that are shared between the go.rice package and generated code.
+package embedded
+
+import (
+	"fmt"
+	"path/filepath"
+	"strings"
+	"time"
+)
+
+const (
+	EmbedTypeGo   = 0
+	EmbedTypeSyso = 1
+)
+
+// EmbeddedBox defines an embedded box
+type EmbeddedBox struct {
+	Name      string                   // box name
+	Time      time.Time                // embed time
+	EmbedType int                      // kind of embedding
+	Files     map[string]*EmbeddedFile // ALL embedded files by full path
+	Dirs      map[string]*EmbeddedDir  // ALL embedded dirs by full path
+}
+
+// Link creates the ChildDirs and ChildFiles links in all EmbeddedDir's
+func (e *EmbeddedBox) Link() {
+	for path, ed := range e.Dirs {
+		fmt.Println(path)
+		ed.ChildDirs = make([]*EmbeddedDir, 0)
+		ed.ChildFiles = make([]*EmbeddedFile, 0)
+	}
+	for path, ed := range e.Dirs {
+		parentDirpath, _ := filepath.Split(path)
+		if strings.HasSuffix(parentDirpath, "/") {
+			parentDirpath = parentDirpath[:len(parentDirpath)-1]
+		}
+		parentDir := e.Dirs[parentDirpath]
+		if parentDir == nil {
+			panic("parentDir `" + parentDirpath + "` is missing in embedded box")
+		}
+		parentDir.ChildDirs = append(parentDir.ChildDirs, ed)
+	}
+	for path, ef := range e.Files {
+		dirpath, _ := filepath.Split(path)
+		if strings.HasSuffix(dirpath, "/") {
+			dirpath = dirpath[:len(dirpath)-1]
+		}
+		dir := e.Dirs[dirpath]
+		if dir == nil {
+			panic("dir `" + dirpath + "` is missing in embedded box")
+		}
+		dir.ChildFiles = append(dir.ChildFiles, ef)
+	}
+}
+
+// EmbeddedDir is instanced in the code generated by the rice tool and contains all necicary information about an embedded file
+type EmbeddedDir struct {
+	Filename   string
+	DirModTime time.Time
+	ChildDirs  []*EmbeddedDir  // direct childs, as returned by virtualDir.Readdir()
+	ChildFiles []*EmbeddedFile // direct childs, as returned by virtualDir.Readdir()
+}
+
+// EmbeddedFile is instanced in the code generated by the rice tool and contains all necicary information about an embedded file
+type EmbeddedFile struct {
+	Filename    string // filename
+	FileModTime time.Time
+	Content     string
+}
+
+// EmbeddedBoxes is a public register of embedded boxes
+var EmbeddedBoxes = make(map[string]*EmbeddedBox)
+
+// RegisterEmbeddedBox registers an EmbeddedBox
+func RegisterEmbeddedBox(name string, box *EmbeddedBox) {
+	if _, exists := EmbeddedBoxes[name]; exists {
+		panic(fmt.Sprintf("EmbeddedBox with name `%s` exists already", name))
+	}
+	EmbeddedBoxes[name] = box
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/example/example.go b/vendor/github.com/GeertJohan/go.rice/example/example.go
new file mode 100644
index 00000000..68f189f3
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/example/example.go
@@ -0,0 +1,69 @@
+package main
+
+import (
+	"encoding/hex"
+	"fmt"
+	"log"
+	"net/http"
+	"os"
+	"text/template"
+
+	"github.com/GeertJohan/go.rice"
+	"github.com/davecgh/go-spew/spew"
+)
+
+func main() {
+	conf := rice.Config{
+		LocateOrder: []rice.LocateMethod{rice.LocateEmbedded, rice.LocateAppended, rice.LocateFS},
+	}
+	box, err := conf.FindBox("example-files")
+	if err != nil {
+		log.Fatalf("error opening rice.Box: %s\n", err)
+	}
+	// spew.Dump(box)
+
+	contentString, err := box.String("file.txt")
+	if err != nil {
+		log.Fatalf("could not read file contents as string: %s\n", err)
+	}
+	log.Printf("Read some file contents as string:\n%s\n", contentString)
+
+	contentBytes, err := box.Bytes("file.txt")
+	if err != nil {
+		log.Fatalf("could not read file contents as byteSlice: %s\n", err)
+	}
+	log.Printf("Read some file contents as byteSlice:\n%s\n", hex.Dump(contentBytes))
+
+	file, err := box.Open("file.txt")
+	if err != nil {
+		log.Fatalf("could not open file: %s\n", err)
+	}
+	spew.Dump(file)
+
+	// find/create a rice.Box
+	templateBox, err := rice.FindBox("example-templates")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// get file contents as string
+	templateString, err := templateBox.String("message.tmpl")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// parse and execute the template
+	tmplMessage, err := template.New("message").Parse(templateString)
+	if err != nil {
+		log.Fatal(err)
+	}
+	tmplMessage.Execute(os.Stdout, map[string]string{"Message": "Hello, world!"})
+
+	http.Handle("/", http.FileServer(box.HTTPBox()))
+	go func() {
+		fmt.Println("Serving files on :8080, press ctrl-C to exit")
+		err := http.ListenAndServe(":8080", nil)
+		if err != nil {
+			log.Fatalf("error serving files: %v", err)
+		}
+	}()
+	select {}
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/file.go b/vendor/github.com/GeertJohan/go.rice/file.go
new file mode 100644
index 00000000..606a1885
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/file.go
@@ -0,0 +1,144 @@
+package rice
+
+import (
+	"bytes"
+	"errors"
+	"os"
+	"path/filepath"
+)
+
+// File implements the io.Reader, io.Seeker, io.Closer and http.File interfaces
+type File struct {
+	// File abstracts file methods so the user doesn't see the difference between rice.virtualFile, rice.virtualDir and os.File
+	// TODO: maybe use internal File interface and four implementations: *os.File, appendedFile, virtualFile, virtualDir
+
+	// real file on disk
+	realF *os.File
+
+	// when embedded (go)
+	virtualF *virtualFile
+	virtualD *virtualDir
+
+	// when appended (zip)
+	appendedF          *appendedFile
+	appendedFileReader *bytes.Reader
+	// TODO: is appendedFileReader subject of races? Might need a lock here..
+}
+
+// Close is like (*os.File).Close()
+// Visit http://golang.org/pkg/os/#File.Close for more information
+func (f *File) Close() error {
+	if f.appendedF != nil {
+		if f.appendedFileReader == nil {
+			return errors.New("already closed")
+		}
+		f.appendedFileReader = nil
+		return nil
+	}
+	if f.virtualF != nil {
+		return f.virtualF.close()
+	}
+	if f.virtualD != nil {
+		return f.virtualD.close()
+	}
+	return f.realF.Close()
+}
+
+// Stat is like (*os.File).Stat()
+// Visit http://golang.org/pkg/os/#File.Stat for more information
+func (f *File) Stat() (os.FileInfo, error) {
+	if f.appendedF != nil {
+		if f.appendedF.dir {
+			return f.appendedF.dirInfo, nil
+		}
+		if f.appendedFileReader == nil {
+			return nil, errors.New("file is closed")
+		}
+		return f.appendedF.zipFile.FileInfo(), nil
+	}
+	if f.virtualF != nil {
+		return f.virtualF.stat()
+	}
+	if f.virtualD != nil {
+		return f.virtualD.stat()
+	}
+	return f.realF.Stat()
+}
+
+// Readdir is like (*os.File).Readdir()
+// Visit http://golang.org/pkg/os/#File.Readdir for more information
+func (f *File) Readdir(count int) ([]os.FileInfo, error) {
+	if f.appendedF != nil {
+		if f.appendedF.dir {
+			fi := make([]os.FileInfo, 0, len(f.appendedF.children))
+			for _, childAppendedFile := range f.appendedF.children {
+				if childAppendedFile.dir {
+					fi = append(fi, childAppendedFile.dirInfo)
+				} else {
+					fi = append(fi, childAppendedFile.zipFile.FileInfo())
+				}
+			}
+			return fi, nil
+		}
+		//++ TODO: is os.ErrInvalid the correct error for Readdir on file?
+		return nil, os.ErrInvalid
+	}
+	if f.virtualF != nil {
+		return f.virtualF.readdir(count)
+	}
+	if f.virtualD != nil {
+		return f.virtualD.readdir(count)
+	}
+	return f.realF.Readdir(count)
+}
+
+// Read is like (*os.File).Read()
+// Visit http://golang.org/pkg/os/#File.Read for more information
+func (f *File) Read(bts []byte) (int, error) {
+	if f.appendedF != nil {
+		if f.appendedFileReader == nil {
+			return 0, &os.PathError{
+				Op:   "read",
+				Path: filepath.Base(f.appendedF.zipFile.Name),
+				Err:  errors.New("file is closed"),
+			}
+		}
+		if f.appendedF.dir {
+			return 0, &os.PathError{
+				Op:   "read",
+				Path: filepath.Base(f.appendedF.zipFile.Name),
+				Err:  errors.New("is a directory"),
+			}
+		}
+		return f.appendedFileReader.Read(bts)
+	}
+	if f.virtualF != nil {
+		return f.virtualF.read(bts)
+	}
+	if f.virtualD != nil {
+		return f.virtualD.read(bts)
+	}
+	return f.realF.Read(bts)
+}
+
+// Seek is like (*os.File).Seek()
+// Visit http://golang.org/pkg/os/#File.Seek for more information
+func (f *File) Seek(offset int64, whence int) (int64, error) {
+	if f.appendedF != nil {
+		if f.appendedFileReader == nil {
+			return 0, &os.PathError{
+				Op:   "seek",
+				Path: filepath.Base(f.appendedF.zipFile.Name),
+				Err:  errors.New("file is closed"),
+			}
+		}
+		return f.appendedFileReader.Seek(offset, whence)
+	}
+	if f.virtualF != nil {
+		return f.virtualF.seek(offset, whence)
+	}
+	if f.virtualD != nil {
+		return f.virtualD.seek(offset, whence)
+	}
+	return f.realF.Seek(offset, whence)
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/http.go b/vendor/github.com/GeertJohan/go.rice/http.go
new file mode 100644
index 00000000..3a61f0e1
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/http.go
@@ -0,0 +1,21 @@
+package rice
+
+import (
+	"net/http"
+)
+
+// HTTPBox implements http.FileSystem which allows the use of Box with a http.FileServer.
+//   e.g.: http.Handle("/", http.FileServer(rice.MustFindBox("http-files").HTTPBox()))
+type HTTPBox struct {
+	*Box
+}
+
+// HTTPBox creates a new HTTPBox from an existing Box
+func (b *Box) HTTPBox() *HTTPBox {
+	return &HTTPBox{b}
+}
+
+// Open returns a File using the http.File interface
+func (hb *HTTPBox) Open(name string) (http.File, error) {
+	return hb.Box.Open(name)
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/append.go b/vendor/github.com/GeertJohan/go.rice/rice/append.go
new file mode 100644
index 00000000..ae3d95fd
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/append.go
@@ -0,0 +1,172 @@
+package main
+
+import (
+	"archive/zip"
+	"fmt"
+	"go/build"
+	"io"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"time"
+
+	"github.com/daaku/go.zipexe"
+)
+
+func operationAppend(pkgs []*build.Package) {
+	if runtime.GOOS == "windows" {
+		_, err := exec.LookPath("zip")
+		if err != nil {
+			fmt.Println("#### WARNING ! ####")
+			fmt.Println("`rice append` is known not to work under windows because the `zip` command is not available. Please let me know if you got this to work (and how).")
+		}
+	}
+
+	// MARKED FOR DELETION
+	// This is actually not required, the append command now has the option --exec required.
+	// // check if package is a command
+	// if !pkg.IsCommand() {
+	// 	fmt.Println("Error: can not append to non-main package. Please follow instructions at github.com/GeertJohan/go.rice")
+	// 	os.Exit(1)
+	// }
+
+	// create tmp zipfile
+	tmpZipfileName := filepath.Join(os.TempDir(), fmt.Sprintf("ricebox-%d-%s.zip", time.Now().Unix(), randomString(10)))
+	verbosef("Will create tmp zipfile: %s\n", tmpZipfileName)
+	tmpZipfile, err := os.Create(tmpZipfileName)
+	if err != nil {
+		fmt.Printf("Error creating tmp zipfile: %s\n", err)
+		os.Exit(1)
+	}
+	defer func() {
+		tmpZipfile.Close()
+		os.Remove(tmpZipfileName)
+	}()
+
+	// find abs path for binary file
+	binfileName, err := filepath.Abs(flags.Append.Executable)
+	if err != nil {
+		fmt.Printf("Error finding absolute path for executable to append: %s\n", err)
+		os.Exit(1)
+	}
+	verbosef("Will append to file: %s\n", binfileName)
+
+	// check that command doesn't already have zip appended
+	if rd, _ := zipexe.Open(binfileName); rd != nil {
+		fmt.Printf("Cannot append to already appended executable. Please remove %s and build a fresh one.\n", binfileName)
+		os.Exit(1)
+	}
+
+	// open binfile
+	binfile, err := os.OpenFile(binfileName, os.O_WRONLY, os.ModeAppend)
+	if err != nil {
+		fmt.Printf("Error: unable to open executable file: %s\n", err)
+		os.Exit(1)
+	}
+
+	// create zip.Writer
+	zipWriter := zip.NewWriter(tmpZipfile)
+
+	for _, pkg := range pkgs {
+		// find boxes for this command
+		boxMap := findBoxes(pkg)
+
+		// notify user when no calls to rice.FindBox are made (is this an error and therefore os.Exit(1) ?
+		if len(boxMap) == 0 {
+			fmt.Printf("no calls to rice.FindBox() or rice.MustFindBox() found in import path `%s`\n", pkg.ImportPath)
+			continue
+		}
+
+		verbosef("\n")
+
+		for boxname := range boxMap {
+			appendedBoxName := strings.Replace(boxname, `/`, `-`, -1)
+
+			// walk box path's and insert files
+			boxPath := filepath.Clean(filepath.Join(pkg.Dir, boxname))
+			filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
+				if info == nil {
+					fmt.Printf("Error: box \"%s\" not found on disk\n", path)
+					os.Exit(1)
+				}
+				// create zipFilename
+				zipFileName := filepath.Join(appendedBoxName, strings.TrimPrefix(path, boxPath))
+				// write directories as empty file with comment "dir"
+				if info.IsDir() {
+					_, err := zipWriter.CreateHeader(&zip.FileHeader{
+						Name:    zipFileName,
+						Comment: "dir",
+					})
+					if err != nil {
+						fmt.Printf("Error creating dir in tmp zip: %s\n", err)
+						os.Exit(1)
+					}
+					return nil
+				}
+
+				// create zipFileWriter
+				zipFileHeader, err := zip.FileInfoHeader(info)
+				if err != nil {
+					fmt.Printf("Error creating zip FileHeader: %v\n", err)
+					os.Exit(1)
+				}
+				zipFileHeader.Name = zipFileName
+				zipFileWriter, err := zipWriter.CreateHeader(zipFileHeader)
+				if err != nil {
+					fmt.Printf("Error creating file in tmp zip: %s\n", err)
+					os.Exit(1)
+				}
+				srcFile, err := os.Open(path)
+				if err != nil {
+					fmt.Printf("Error opening file to append: %s\n", err)
+					os.Exit(1)
+				}
+				_, err = io.Copy(zipFileWriter, srcFile)
+				if err != nil {
+					fmt.Printf("Error copying file contents to zip: %s\n", err)
+					os.Exit(1)
+				}
+				srcFile.Close()
+
+				return nil
+			})
+		}
+	}
+
+	err = zipWriter.Close()
+	if err != nil {
+		fmt.Printf("Error closing tmp zipfile: %s\n", err)
+		os.Exit(1)
+	}
+
+	err = tmpZipfile.Sync()
+	if err != nil {
+		fmt.Printf("Error syncing tmp zipfile: %s\n", err)
+		os.Exit(1)
+	}
+	_, err = tmpZipfile.Seek(0, 0)
+	if err != nil {
+		fmt.Printf("Error seeking tmp zipfile: %s\n", err)
+		os.Exit(1)
+	}
+	_, err = binfile.Seek(0, 2)
+	if err != nil {
+		fmt.Printf("Error seeking bin file: %s\n", err)
+		os.Exit(1)
+	}
+
+	_, err = io.Copy(binfile, tmpZipfile)
+	if err != nil {
+		fmt.Printf("Error appending zipfile to executable: %s\n", err)
+		os.Exit(1)
+	}
+
+	zipA := exec.Command("zip", "-A", binfileName)
+	err = zipA.Run()
+	if err != nil {
+		fmt.Printf("Error setting zip offset: %s\n", err)
+		os.Exit(1)
+	}
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/clean.go b/vendor/github.com/GeertJohan/go.rice/rice/clean.go
new file mode 100644
index 00000000..6155c064
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/clean.go
@@ -0,0 +1,33 @@
+package main
+
+import (
+	"fmt"
+	"go/build"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+func operationClean(pkg *build.Package) {
+	filepath.Walk(pkg.Dir, func(filename string, info os.FileInfo, err error) error {
+		if err != nil {
+			fmt.Printf("error walking pkg dir to clean files: %v\n", err)
+			os.Exit(1)
+		}
+		if info.IsDir() {
+			return nil
+		}
+		verbosef("checking file '%s'\n", filename)
+		if filepath.Base(filename) == "rice-box.go" ||
+			strings.HasSuffix(filename, ".rice-box.go") ||
+			strings.HasSuffix(filename, ".rice-box.syso") {
+			err := os.Remove(filename)
+			if err != nil {
+				fmt.Printf("error removing file (%s): %s\n", filename, err)
+				os.Exit(-1)
+			}
+			verbosef("removed file '%s'\n", filename)
+		}
+		return nil
+	})
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/embed-go.go b/vendor/github.com/GeertJohan/go.rice/rice/embed-go.go
new file mode 100644
index 00000000..c5a0e9e8
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/embed-go.go
@@ -0,0 +1,158 @@
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"go/build"
+	"go/format"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+const boxFilename = "rice-box.go"
+
+func operationEmbedGo(pkg *build.Package) {
+
+	boxMap := findBoxes(pkg)
+
+	// notify user when no calls to rice.FindBox are made (is this an error and therefore os.Exit(1) ?
+	if len(boxMap) == 0 {
+		fmt.Println("no calls to rice.FindBox() found")
+		return
+	}
+
+	verbosef("\n")
+	var boxes []*boxDataType
+
+	for boxname := range boxMap {
+		// find path and filename for this box
+		boxPath := filepath.Join(pkg.Dir, boxname)
+
+		// Check to see if the path for the box is a symbolic link.  If so, simply
+		// box what the symbolic link points to.  Note: the filepath.Walk function
+		// will NOT follow any nested symbolic links.  This only handles the case
+		// where the root of the box is a symbolic link.
+		symPath, serr := os.Readlink(boxPath)
+		if serr == nil {
+			boxPath = symPath
+		}
+
+		// verbose info
+		verbosef("embedding box '%s' to '%s'\n", boxname, boxFilename)
+
+		// read box metadata
+		boxInfo, ierr := os.Stat(boxPath)
+		if ierr != nil {
+			fmt.Printf("Error: unable to access box at %s\n", boxPath)
+			os.Exit(1)
+		}
+
+		// create box datastructure (used by template)
+		box := &boxDataType{
+			BoxName: boxname,
+			UnixNow: boxInfo.ModTime().Unix(),
+			Files:   make([]*fileDataType, 0),
+			Dirs:    make(map[string]*dirDataType),
+		}
+
+		if !boxInfo.IsDir() {
+			fmt.Printf("Error: Box %s must point to a directory but points to %s instead\n",
+				boxname, boxPath)
+			os.Exit(1)
+		}
+
+		// fill box datastructure with file data
+		filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
+			if err != nil {
+				fmt.Printf("error walking box: %s\n", err)
+				os.Exit(1)
+			}
+
+			filename := strings.TrimPrefix(path, boxPath)
+			filename = strings.Replace(filename, "\\", "/", -1)
+			filename = strings.TrimPrefix(filename, "/")
+			if info.IsDir() {
+				dirData := &dirDataType{
+					Identifier: "dir" + nextIdentifier(),
+					FileName:   filename,
+					ModTime:    info.ModTime().Unix(),
+					ChildFiles: make([]*fileDataType, 0),
+					ChildDirs:  make([]*dirDataType, 0),
+				}
+				verbosef("\tincludes dir: '%s'\n", dirData.FileName)
+				box.Dirs[dirData.FileName] = dirData
+
+				// add tree entry (skip for root, it'll create a recursion)
+				if dirData.FileName != "" {
+					pathParts := strings.Split(dirData.FileName, "/")
+					parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
+					parentDir.ChildDirs = append(parentDir.ChildDirs, dirData)
+				}
+			} else {
+				fileData := &fileDataType{
+					Identifier: "file" + nextIdentifier(),
+					FileName:   filename,
+					ModTime:    info.ModTime().Unix(),
+				}
+				verbosef("\tincludes file: '%s'\n", fileData.FileName)
+				fileData.Content, err = ioutil.ReadFile(path)
+				if err != nil {
+					fmt.Printf("error reading file content while walking box: %s\n", err)
+					os.Exit(1)
+				}
+				box.Files = append(box.Files, fileData)
+
+				// add tree entry
+				pathParts := strings.Split(fileData.FileName, "/")
+				parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
+				if parentDir == nil {
+					fmt.Printf("Error: parent of %s is not within the box\n", path)
+					os.Exit(1)
+				}
+				parentDir.ChildFiles = append(parentDir.ChildFiles, fileData)
+			}
+			return nil
+		})
+		boxes = append(boxes, box)
+
+	}
+
+	embedSourceUnformated := bytes.NewBuffer(make([]byte, 0))
+
+	// execute template to buffer
+	err := tmplEmbeddedBox.Execute(
+		embedSourceUnformated,
+		embedFileDataType{pkg.Name, boxes},
+	)
+	if err != nil {
+		log.Printf("error writing embedded box to file (template execute): %s\n", err)
+		os.Exit(1)
+	}
+
+	// format the source code
+	embedSource, err := format.Source(embedSourceUnformated.Bytes())
+	if err != nil {
+		log.Printf("error formatting embedSource: %s\n", err)
+		os.Exit(1)
+	}
+
+	// create go file for box
+	boxFile, err := os.Create(filepath.Join(pkg.Dir, boxFilename))
+	if err != nil {
+		log.Printf("error creating embedded box file: %s\n", err)
+		os.Exit(1)
+	}
+	defer boxFile.Close()
+
+	// write source to file
+	_, err = io.Copy(boxFile, bytes.NewBuffer(embedSource))
+	if err != nil {
+		log.Printf("error writing embedSource to file: %s\n", err)
+		os.Exit(1)
+	}
+
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/embed-syso.go b/vendor/github.com/GeertJohan/go.rice/rice/embed-syso.go
new file mode 100644
index 00000000..beef3ea7
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/embed-syso.go
@@ -0,0 +1,204 @@
+package main
+
+import (
+	"bytes"
+	"encoding/gob"
+	"fmt"
+	"go/build"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"text/template"
+
+	"github.com/GeertJohan/go.rice/embedded"
+	"github.com/akavel/rsrc/coff"
+)
+
+type sizedReader struct {
+	*bytes.Reader
+}
+
+func (s sizedReader) Size() int64 {
+	return int64(s.Len())
+}
+
+var tmplEmbeddedSysoHelper *template.Template
+
+func init() {
+	var err error
+	tmplEmbeddedSysoHelper, err = template.New("embeddedSysoHelper").Parse(`package {{.Package}}
+// ############# GENERATED CODE #####################
+// ## This file was generated by the rice tool.
+// ## Do not edit unless you know what you're doing.
+// ##################################################
+
+// extern char _bricebox_{{.Symname}}[], _ericebox_{{.Symname}};
+// int get_{{.Symname}}_length() {
+// 	return &_ericebox_{{.Symname}} - _bricebox_{{.Symname}};
+// }
+import "C"
+import (
+	"bytes"
+	"encoding/gob"
+	"github.com/GeertJohan/go.rice/embedded"
+	"unsafe"
+)
+
+func init() {
+	ptr := unsafe.Pointer(&C._bricebox_{{.Symname}})
+	bts := C.GoBytes(ptr, C.get_{{.Symname}}_length())
+	embeddedBox := &embedded.EmbeddedBox{}
+	err := gob.NewDecoder(bytes.NewReader(bts)).Decode(embeddedBox)
+	if err != nil {
+		panic("error decoding embedded box: "+err.Error())
+	}
+	embeddedBox.Link()
+	embedded.RegisterEmbeddedBox(embeddedBox.Name, embeddedBox)
+}`)
+	if err != nil {
+		panic("could not parse template embeddedSysoHelper: " + err.Error())
+	}
+}
+
+type embeddedSysoHelperData struct {
+	Package string
+	Symname string
+}
+
+func operationEmbedSyso(pkg *build.Package) {
+
+	regexpSynameReplacer := regexp.MustCompile(`[^a-z0-9_]`)
+
+	boxMap := findBoxes(pkg)
+
+	// notify user when no calls to rice.FindBox are made (is this an error and therefore os.Exit(1) ?
+	if len(boxMap) == 0 {
+		fmt.Println("no calls to rice.FindBox() found")
+		return
+	}
+
+	verbosef("\n")
+
+	for boxname := range boxMap {
+		// find path and filename for this box
+		boxPath := filepath.Join(pkg.Dir, boxname)
+		boxFilename := strings.Replace(boxname, "/", "-", -1)
+		boxFilename = strings.Replace(boxFilename, "..", "back", -1)
+		boxFilename = strings.Replace(boxFilename, ".", "-", -1)
+
+		// verbose info
+		verbosef("embedding box '%s'\n", boxname)
+		verbosef("\tto file %s\n", boxFilename)
+
+		// read box metadata
+		boxInfo, ierr := os.Stat(boxPath)
+		if ierr != nil {
+			fmt.Printf("Error: unable to access box at %s\n", boxPath)
+			os.Exit(1)
+		}
+
+		// create box datastructure (used by template)
+		box := &embedded.EmbeddedBox{
+			Name:      boxname,
+			Time:      boxInfo.ModTime(),
+			EmbedType: embedded.EmbedTypeSyso,
+			Files:     make(map[string]*embedded.EmbeddedFile),
+			Dirs:      make(map[string]*embedded.EmbeddedDir),
+		}
+
+		// fill box datastructure with file data
+		filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
+			if err != nil {
+				fmt.Printf("error walking box: %s\n", err)
+				os.Exit(1)
+			}
+
+			filename := strings.TrimPrefix(path, boxPath)
+			filename = strings.Replace(filename, "\\", "/", -1)
+			filename = strings.TrimPrefix(filename, "/")
+			if info.IsDir() {
+				embeddedDir := &embedded.EmbeddedDir{
+					Filename:   filename,
+					DirModTime: info.ModTime(),
+				}
+				verbosef("\tincludes dir: '%s'\n", embeddedDir.Filename)
+				box.Dirs[embeddedDir.Filename] = embeddedDir
+
+				// add tree entry (skip for root, it'll create a recursion)
+				if embeddedDir.Filename != "" {
+					pathParts := strings.Split(embeddedDir.Filename, "/")
+					parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
+					parentDir.ChildDirs = append(parentDir.ChildDirs, embeddedDir)
+				}
+			} else {
+				embeddedFile := &embedded.EmbeddedFile{
+					Filename:    filename,
+					FileModTime: info.ModTime(),
+					Content:     "",
+				}
+				verbosef("\tincludes file: '%s'\n", embeddedFile.Filename)
+				contentBytes, err := ioutil.ReadFile(path)
+				if err != nil {
+					fmt.Printf("error reading file content while walking box: %s\n", err)
+					os.Exit(1)
+				}
+				embeddedFile.Content = string(contentBytes)
+				box.Files[embeddedFile.Filename] = embeddedFile
+			}
+			return nil
+		})
+
+		// encode embedded box to gob file
+		boxGobBuf := &bytes.Buffer{}
+		err := gob.NewEncoder(boxGobBuf).Encode(box)
+		if err != nil {
+			fmt.Printf("error encoding box to gob: %v\n", err)
+			os.Exit(1)
+		}
+
+		verbosef("gob-encoded embeddedBox is %d bytes large\n", boxGobBuf.Len())
+
+		// write coff
+		symname := regexpSynameReplacer.ReplaceAllString(boxname, "_")
+		createCoffSyso(boxname, symname, "386", boxGobBuf.Bytes())
+		createCoffSyso(boxname, symname, "amd64", boxGobBuf.Bytes())
+
+		// write go
+		sysoHelperData := embeddedSysoHelperData{
+			Package: pkg.Name,
+			Symname: symname,
+		}
+		fileSysoHelper, err := os.Create(boxFilename + ".rice-box.go")
+		if err != nil {
+			fmt.Printf("error creating syso helper: %v\n", err)
+			os.Exit(1)
+		}
+		err = tmplEmbeddedSysoHelper.Execute(fileSysoHelper, sysoHelperData)
+		if err != nil {
+			fmt.Printf("error executing tmplEmbeddedSysoHelper: %v\n", err)
+			os.Exit(1)
+		}
+	}
+}
+
+func createCoffSyso(boxFilename string, symname string, arch string, data []byte) {
+	boxCoff := coff.NewRDATA()
+	switch arch {
+	case "386":
+	case "amd64":
+		boxCoff.FileHeader.Machine = 0x8664
+	default:
+		panic("invalid arch")
+	}
+	boxCoff.AddData("_bricebox_"+symname, sizedReader{bytes.NewReader(data)})
+	boxCoff.AddData("_ericebox_"+symname, io.NewSectionReader(strings.NewReader("\000\000"), 0, 2)) // TODO: why? copied from rsrc, which copied it from as-generated
+	boxCoff.Freeze()
+	err := writeCoff(boxCoff, boxFilename+"_"+arch+".rice-box.syso")
+	if err != nil {
+		fmt.Printf("error writing %s coff/.syso: %v\n", arch, err)
+		os.Exit(1)
+	}
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/find.go b/vendor/github.com/GeertJohan/go.rice/rice/find.go
new file mode 100644
index 00000000..6d78eeaa
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/find.go
@@ -0,0 +1,150 @@
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/parser"
+	"go/token"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+func badArgument(fileset *token.FileSet, p token.Pos) {
+	pos := fileset.Position(p)
+	filename := pos.Filename
+	base, err := os.Getwd()
+	if err == nil {
+		rpath, perr := filepath.Rel(base, pos.Filename)
+		if perr == nil {
+			filename = rpath
+		}
+	}
+	msg := fmt.Sprintf("%s:%d: Error: found call to rice.FindBox, "+
+		"but argument must be a string literal.\n", filename, pos.Line)
+	fmt.Println(msg)
+	os.Exit(1)
+}
+
+func findBoxes(pkg *build.Package) map[string]bool {
+	// create map of boxes to embed
+	var boxMap = make(map[string]bool)
+
+	// create one list of files for this package
+	filenames := make([]string, 0, len(pkg.GoFiles)+len(pkg.CgoFiles))
+	filenames = append(filenames, pkg.GoFiles...)
+	filenames = append(filenames, pkg.CgoFiles...)
+
+	// loop over files, search for rice.FindBox(..) calls
+	for _, filename := range filenames {
+		// find full filepath
+		fullpath := filepath.Join(pkg.Dir, filename)
+		if strings.HasSuffix(filename, "rice-box.go") {
+			// Ignore *.rice-box.go files
+			verbosef("skipping file %q\n", fullpath)
+			continue
+		}
+		verbosef("scanning file %q\n", fullpath)
+
+		fset := token.NewFileSet()
+		f, err := parser.ParseFile(fset, fullpath, nil, 0)
+		if err != nil {
+			fmt.Println(err)
+			os.Exit(1)
+		}
+
+		var riceIsImported bool
+		ricePkgName := "rice"
+		for _, imp := range f.Imports {
+			if strings.HasSuffix(imp.Path.Value, "go.rice\"") {
+				if imp.Name != nil {
+					ricePkgName = imp.Name.Name
+				}
+				riceIsImported = true
+				break
+			}
+		}
+		if !riceIsImported {
+			// Rice wasn't imported, so we won't find a box.
+			continue
+		}
+		if ricePkgName == "_" {
+			// Rice pkg is unnamed, so we won't find a box.
+			continue
+		}
+
+		// Inspect AST, looking for calls to (Must)?FindBox.
+		// First parameter of the func must be a basic literal.
+		// Identifiers won't be resolved.
+		var nextIdentIsBoxFunc bool
+		var nextBasicLitParamIsBoxName bool
+		var boxCall token.Pos
+		var variableToRemember string
+		var validVariablesForBoxes map[string]bool = make(map[string]bool)
+
+		ast.Inspect(f, func(node ast.Node) bool {
+			if node == nil {
+				return false
+			}
+			switch x := node.(type) {
+			// this case fixes the var := func() style assignments, not assignments to vars declared separately from the assignment.
+			case *ast.AssignStmt:
+				var assign = node.(*ast.AssignStmt)
+				name, found := assign.Lhs[0].(*ast.Ident)
+				if found {
+					variableToRemember = name.Name
+					composite, first := assign.Rhs[0].(*ast.CompositeLit)
+					if first {
+						riceSelector, second := composite.Type.(*ast.SelectorExpr)
+
+						if second {
+							callCorrect := riceSelector.Sel.Name == "Config"
+							packageName, third := riceSelector.X.(*ast.Ident)
+
+							if third && callCorrect && packageName.Name == ricePkgName {
+								validVariablesForBoxes[name.Name] = true
+								verbosef("\tfound variable, saving to scan for boxes: %q\n", name.Name)
+							}
+						}
+					}
+				}
+			case *ast.Ident:
+				if nextIdentIsBoxFunc || ricePkgName == "." {
+					nextIdentIsBoxFunc = false
+					if x.Name == "FindBox" || x.Name == "MustFindBox" {
+						nextBasicLitParamIsBoxName = true
+						boxCall = x.Pos()
+					}
+				} else {
+					if x.Name == ricePkgName || validVariablesForBoxes[x.Name] {
+						nextIdentIsBoxFunc = true
+					}
+				}
+			case *ast.BasicLit:
+				if nextBasicLitParamIsBoxName {
+					if x.Kind == token.STRING {
+						nextBasicLitParamIsBoxName = false
+						// trim "" or ``
+						name := x.Value[1 : len(x.Value)-1]
+						boxMap[name] = true
+						verbosef("\tfound box %q\n", name)
+					} else {
+						badArgument(fset, boxCall)
+					}
+				}
+
+			default:
+				if nextIdentIsBoxFunc {
+					nextIdentIsBoxFunc = false
+				}
+				if nextBasicLitParamIsBoxName {
+					badArgument(fset, boxCall)
+				}
+			}
+			return true
+		})
+	}
+
+	return boxMap
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/flags.go b/vendor/github.com/GeertJohan/go.rice/rice/flags.go
new file mode 100644
index 00000000..167fea80
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/flags.go
@@ -0,0 +1,80 @@
+package main
+
+import (
+	"fmt"
+	"go/build"
+	"os"
+
+	goflags "github.com/jessevdk/go-flags" // rename import to `goflags` (file scope) so we can use `var flags` (package scope)
+)
+
+// flags
+var flags struct {
+	Verbose     bool     `long:"verbose" short:"v" description:"Show verbose debug information"`
+	ImportPaths []string `long:"import-path" short:"i" description:"Import path(s) to use. Using PWD when left empty. Specify multiple times for more import paths to append"`
+
+	Append struct {
+		Executable string `long:"exec" description:"Executable to append" required:"true"`
+	} `command:"append"`
+
+	EmbedGo   struct{} `command:"embed-go" alias:"embed"`
+	EmbedSyso struct{} `command:"embed-syso"`
+	Clean     struct{} `command:"clean"`
+}
+
+// flags parser
+var flagsParser *goflags.Parser
+
+// initFlags parses the given flags.
+// when the user asks for help (-h or --help): the application exists with status 0
+// when unexpected flags is given: the application exits with status 1
+func parseArguments() {
+	// create flags parser in global var, for flagsParser.Active.Name (operation)
+	flagsParser = goflags.NewParser(&flags, goflags.Default)
+
+	// parse flags
+	args, err := flagsParser.Parse()
+	if err != nil {
+		// assert the err to be a flags.Error
+		flagError := err.(*goflags.Error)
+		if flagError.Type == goflags.ErrHelp {
+			// user asked for help on flags.
+			// program can exit successfully
+			os.Exit(0)
+		}
+		if flagError.Type == goflags.ErrUnknownFlag {
+			fmt.Println("Use --help to view available options.")
+			os.Exit(1)
+		}
+		if flagError.Type == goflags.ErrRequired {
+			os.Exit(1)
+		}
+		fmt.Printf("Error parsing flags: %s\n", err)
+		os.Exit(1)
+	}
+
+	// error on left-over arguments
+	if len(args) > 0 {
+		fmt.Printf("Unexpected arguments: %s\nUse --help to view available options.", args)
+		os.Exit(1)
+	}
+
+	// default ImportPath to pwd when not set
+	if len(flags.ImportPaths) == 0 {
+		pwd, err := os.Getwd()
+		if err != nil {
+			fmt.Printf("error getting pwd: %s\n", err)
+			os.Exit(1)
+		}
+		verbosef("using pwd as import path\n")
+		// find non-absolute path for this pwd
+		pkg, err := build.ImportDir(pwd, build.FindOnly)
+		if err != nil {
+			fmt.Printf("error using current directory as import path: %s\n", err)
+			os.Exit(1)
+		}
+		flags.ImportPaths = append(flags.ImportPaths, pkg.ImportPath)
+		verbosef("using import paths: %s\n", flags.ImportPaths)
+		return
+	}
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/identifier.go b/vendor/github.com/GeertJohan/go.rice/rice/identifier.go
new file mode 100644
index 00000000..445ee7da
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/identifier.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+	"strconv"
+
+	"github.com/GeertJohan/go.incremental"
+)
+
+var identifierCount incremental.Uint64
+
+func nextIdentifier() string {
+	num := identifierCount.Next()
+	return strconv.FormatUint(num, 36) // 0123456789abcdefghijklmnopqrstuvwxyz
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/main.go b/vendor/github.com/GeertJohan/go.rice/rice/main.go
new file mode 100644
index 00000000..7bac5fa3
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/main.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+	"fmt"
+	"go/build"
+	"log"
+	"os"
+)
+
+func main() {
+	// parser arguments
+	parseArguments()
+
+	// find package for path
+	var pkgs []*build.Package
+	for _, importPath := range flags.ImportPaths {
+		pkg := pkgForPath(importPath)
+		pkgs = append(pkgs, pkg)
+	}
+
+	// switch on the operation to perform
+	switch flagsParser.Active.Name {
+	case "embed", "embed-go":
+		for _, pkg := range pkgs {
+			operationEmbedGo(pkg)
+		}
+	case "embed-syso":
+		log.Println("WARNING: embedding .syso is experimental..")
+		for _, pkg := range pkgs {
+			operationEmbedSyso(pkg)
+		}
+	case "append":
+		operationAppend(pkgs)
+	case "clean":
+		for _, pkg := range pkgs {
+			operationClean(pkg)
+		}
+	}
+
+	// all done
+	verbosef("\n")
+	verbosef("rice finished successfully\n")
+}
+
+// helper function to get *build.Package for given path
+func pkgForPath(path string) *build.Package {
+	// get pwd for relative imports
+	pwd, err := os.Getwd()
+	if err != nil {
+		fmt.Printf("error getting pwd (required for relative imports): %s\n", err)
+		os.Exit(1)
+	}
+
+	// read full package information
+	pkg, err := build.Import(path, pwd, 0)
+	if err != nil {
+		fmt.Printf("error reading package: %s\n", err)
+		os.Exit(1)
+	}
+
+	return pkg
+}
+
+func verbosef(format string, stuff ...interface{}) {
+	if flags.Verbose {
+		log.Printf(format, stuff...)
+	}
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/templates.go b/vendor/github.com/GeertJohan/go.rice/rice/templates.go
new file mode 100644
index 00000000..02561ca0
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/templates.go
@@ -0,0 +1,98 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"text/template"
+)
+
+var tmplEmbeddedBox *template.Template
+
+func init() {
+	var err error
+
+	// parse embedded box template
+	tmplEmbeddedBox, err = template.New("embeddedBox").Parse(`package {{.Package}}
+
+import (
+	"github.com/GeertJohan/go.rice/embedded"
+	"time"
+)
+
+{{range .Boxes}}
+func init() {
+
+	// define files
+	{{range .Files}}{{.Identifier}} := &embedded.EmbeddedFile{
+		Filename:    ` + "`" + `{{.FileName}}` + "`" + `,
+		FileModTime: time.Unix({{.ModTime}}, 0),
+		Content:     string({{.Content | printf "%q"}}), 
+	}
+	{{end}}
+
+	// define dirs
+	{{range .Dirs}}{{.Identifier}} := &embedded.EmbeddedDir{
+		Filename:    ` + "`" + `{{.FileName}}` + "`" + `,
+		DirModTime: time.Unix({{.ModTime}}, 0),
+		ChildFiles:  []*embedded.EmbeddedFile{
+			{{range .ChildFiles}}{{.Identifier}}, // {{.FileName}}
+			{{end}}
+		},
+	}
+	{{end}}
+
+	// link ChildDirs
+	{{range .Dirs}}{{.Identifier}}.ChildDirs = []*embedded.EmbeddedDir{
+		{{range .ChildDirs}}{{.Identifier}}, // {{.FileName}}
+		{{end}}
+	}
+	{{end}}
+
+	// register embeddedBox
+	embedded.RegisterEmbeddedBox(` + "`" + `{{.BoxName}}` + "`" + `, &embedded.EmbeddedBox{
+		Name: ` + "`" + `{{.BoxName}}` + "`" + `,
+		Time: time.Unix({{.UnixNow}}, 0),
+		Dirs: map[string]*embedded.EmbeddedDir{
+			{{range .Dirs}}"{{.FileName}}": {{.Identifier}},
+			{{end}}
+		},
+		Files: map[string]*embedded.EmbeddedFile{
+			{{range .Files}}"{{.FileName}}": {{.Identifier}},
+			{{end}}
+		},
+	})
+}
+{{end}}`)
+	if err != nil {
+		fmt.Printf("error parsing embedded box template: %s\n", err)
+		os.Exit(-1)
+	}
+}
+
+type embedFileDataType struct {
+	Package string
+	Boxes   []*boxDataType
+}
+
+type boxDataType struct {
+	BoxName string
+	UnixNow int64
+	Files   []*fileDataType
+	Dirs    map[string]*dirDataType
+}
+
+type fileDataType struct {
+	Identifier string
+	FileName   string
+	Content    []byte
+	ModTime    int64
+}
+
+type dirDataType struct {
+	Identifier string
+	FileName   string
+	Content    []byte
+	ModTime    int64
+	ChildDirs  []*dirDataType
+	ChildFiles []*fileDataType
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/util.go b/vendor/github.com/GeertJohan/go.rice/rice/util.go
new file mode 100644
index 00000000..c9ed4b0a
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/util.go
@@ -0,0 +1,22 @@
+package main
+
+import (
+	"math/rand"
+	"time"
+)
+
+// randomString generates a pseudo-random alpha-numeric string with given length.
+func randomString(length int) string {
+	rand.Seed(time.Now().UnixNano())
+	k := make([]rune, length)
+	for i := 0; i < length; i++ {
+		c := rand.Intn(35)
+		if c < 10 {
+			c += 48 // numbers (0-9) (0+48 == 48 == '0', 9+48 == 57 == '9')
+		} else {
+			c += 87 // lower case alphabets (a-z) (10+87 == 97 == 'a', 35+87 == 122 = 'z')
+		}
+		k[i] = rune(c)
+	}
+	return string(k)
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/writecoff.go b/vendor/github.com/GeertJohan/go.rice/rice/writecoff.go
new file mode 100644
index 00000000..0c12c0ff
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/writecoff.go
@@ -0,0 +1,42 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"reflect"
+
+	"github.com/akavel/rsrc/binutil"
+	"github.com/akavel/rsrc/coff"
+)
+
+// copied from github.com/akavel/rsrc
+// LICENSE: MIT
+// Copyright 2013-2014 The rsrc Authors. (https://github.com/akavel/rsrc/blob/master/AUTHORS)
+func writeCoff(coff *coff.Coff, fnameout string) error {
+	out, err := os.Create(fnameout)
+	if err != nil {
+		return err
+	}
+	defer out.Close()
+	w := binutil.Writer{W: out}
+
+	// write the resulting file to disk
+	binutil.Walk(coff, func(v reflect.Value, path string) error {
+		if binutil.Plain(v.Kind()) {
+			w.WriteLE(v.Interface())
+			return nil
+		}
+		vv, ok := v.Interface().(binutil.SizedReader)
+		if ok {
+			w.WriteFromSized(vv)
+			return binutil.WALK_SKIP
+		}
+		return nil
+	})
+
+	if w.Err != nil {
+		return fmt.Errorf("Error writing output file: %s", w.Err)
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/sort.go b/vendor/github.com/GeertJohan/go.rice/sort.go
new file mode 100644
index 00000000..cd83c658
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/sort.go
@@ -0,0 +1,19 @@
+package rice
+
+import "os"
+
+// SortByName allows an array of os.FileInfo objects
+// to be easily sorted by filename using sort.Sort(SortByName(array))
+type SortByName []os.FileInfo
+
+func (f SortByName) Len() int           { return len(f) }
+func (f SortByName) Less(i, j int) bool { return f[i].Name() < f[j].Name() }
+func (f SortByName) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
+
+// SortByModified allows an array of os.FileInfo objects
+// to be easily sorted by modified date using sort.Sort(SortByModified(array))
+type SortByModified []os.FileInfo
+
+func (f SortByModified) Len() int           { return len(f) }
+func (f SortByModified) Less(i, j int) bool { return f[i].ModTime().Unix() > f[j].ModTime().Unix() }
+func (f SortByModified) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
diff --git a/vendor/github.com/GeertJohan/go.rice/virtual.go b/vendor/github.com/GeertJohan/go.rice/virtual.go
new file mode 100644
index 00000000..50bff167
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/virtual.go
@@ -0,0 +1,252 @@
+package rice
+
+import (
+	"errors"
+	"io"
+	"os"
+	"path/filepath"
+	"sort"
+
+	"github.com/GeertJohan/go.rice/embedded"
+)
+
+//++ TODO: IDEA: merge virtualFile and virtualDir, this decreases work done by rice.File
+
+// Error indicating some function is not implemented yet (but available to satisfy an interface)
+var ErrNotImplemented = errors.New("not implemented yet")
+
+// virtualFile is a 'stateful' virtual file.
+// virtualFile wraps an *EmbeddedFile for a call to Box.Open() and virtualizes 'read cursor' (offset) and 'closing'.
+// virtualFile is only internally visible and should be exposed through rice.File
+type virtualFile struct {
+	*embedded.EmbeddedFile       // the actual embedded file, embedded to obtain methods
+	offset                 int64 // read position on the virtual file
+	closed                 bool  // closed when true
+}
+
+// create a new virtualFile for given EmbeddedFile
+func newVirtualFile(ef *embedded.EmbeddedFile) *virtualFile {
+	vf := &virtualFile{
+		EmbeddedFile: ef,
+		offset:       0,
+		closed:       false,
+	}
+	return vf
+}
+
+//++ TODO check for nil pointers in all these methods. When so: return os.PathError with Err: os.ErrInvalid
+
+func (vf *virtualFile) close() error {
+	if vf.closed {
+		return &os.PathError{
+			Op:   "close",
+			Path: vf.EmbeddedFile.Filename,
+			Err:  errors.New("already closed"),
+		}
+	}
+	vf.EmbeddedFile = nil
+	vf.closed = true
+	return nil
+}
+
+func (vf *virtualFile) stat() (os.FileInfo, error) {
+	if vf.closed {
+		return nil, &os.PathError{
+			Op:   "stat",
+			Path: vf.EmbeddedFile.Filename,
+			Err:  errors.New("bad file descriptor"),
+		}
+	}
+	return (*embeddedFileInfo)(vf.EmbeddedFile), nil
+}
+
+func (vf *virtualFile) readdir(count int) ([]os.FileInfo, error) {
+	if vf.closed {
+		return nil, &os.PathError{
+			Op:   "readdir",
+			Path: vf.EmbeddedFile.Filename,
+			Err:  errors.New("bad file descriptor"),
+		}
+	}
+	//TODO: return proper error for a readdir() call on a file
+	return nil, ErrNotImplemented
+}
+
+func (vf *virtualFile) read(bts []byte) (int, error) {
+	if vf.closed {
+		return 0, &os.PathError{
+			Op:   "read",
+			Path: vf.EmbeddedFile.Filename,
+			Err:  errors.New("bad file descriptor"),
+		}
+	}
+
+	end := vf.offset + int64(len(bts))
+
+	if end >= int64(len(vf.Content)) {
+		// end of file, so return what we have + EOF
+		n := copy(bts, vf.Content[vf.offset:])
+		vf.offset = 0
+		return n, io.EOF
+	}
+
+	n := copy(bts, vf.Content[vf.offset:end])
+	vf.offset += int64(n)
+	return n, nil
+
+}
+
+func (vf *virtualFile) seek(offset int64, whence int) (int64, error) {
+	if vf.closed {
+		return 0, &os.PathError{
+			Op:   "seek",
+			Path: vf.EmbeddedFile.Filename,
+			Err:  errors.New("bad file descriptor"),
+		}
+	}
+	var e error
+
+	//++ TODO: check if this is correct implementation for seek
+	switch whence {
+	case os.SEEK_SET:
+		//++ check if new offset isn't out of bounds, set e when it is, then break out of switch
+		vf.offset = offset
+	case os.SEEK_CUR:
+		//++ check if new offset isn't out of bounds, set e when it is, then break out of switch
+		vf.offset += offset
+	case os.SEEK_END:
+		//++ check if new offset isn't out of bounds, set e when it is, then break out of switch
+		vf.offset = int64(len(vf.EmbeddedFile.Content)) - offset
+	}
+
+	if e != nil {
+		return 0, &os.PathError{
+			Op:   "seek",
+			Path: vf.Filename,
+			Err:  e,
+		}
+	}
+
+	return vf.offset, nil
+}
+
+// virtualDir is a 'stateful' virtual directory.
+// virtualDir wraps an *EmbeddedDir for a call to Box.Open() and virtualizes 'closing'.
+// virtualDir is only internally visible and should be exposed through rice.File
+type virtualDir struct {
+	*embedded.EmbeddedDir
+	offset int // readdir position on the directory
+	closed bool
+}
+
+// create a new virtualDir for given EmbeddedDir
+func newVirtualDir(ed *embedded.EmbeddedDir) *virtualDir {
+	vd := &virtualDir{
+		EmbeddedDir: ed,
+		offset:      0,
+		closed:      false,
+	}
+	return vd
+}
+
+func (vd *virtualDir) close() error {
+	//++ TODO: needs sync mutex?
+	if vd.closed {
+		return &os.PathError{
+			Op:   "close",
+			Path: vd.EmbeddedDir.Filename,
+			Err:  errors.New("already closed"),
+		}
+	}
+	vd.closed = true
+	return nil
+}
+
+func (vd *virtualDir) stat() (os.FileInfo, error) {
+	if vd.closed {
+		return nil, &os.PathError{
+			Op:   "stat",
+			Path: vd.EmbeddedDir.Filename,
+			Err:  errors.New("bad file descriptor"),
+		}
+	}
+	return (*embeddedDirInfo)(vd.EmbeddedDir), nil
+}
+
+func (vd *virtualDir) readdir(n int) (fi []os.FileInfo, err error) {
+
+	if vd.closed {
+		return nil, &os.PathError{
+			Op:   "readdir",
+			Path: vd.EmbeddedDir.Filename,
+			Err:  errors.New("bad file descriptor"),
+		}
+	}
+
+	// Build up the array of our contents
+	var files []os.FileInfo
+
+	// Add the child directories
+	for _, child := range vd.ChildDirs {
+		child.Filename = filepath.Base(child.Filename)
+		files = append(files, (*embeddedDirInfo)(child))
+	}
+
+	// Add the child files
+	for _, child := range vd.ChildFiles {
+		child.Filename = filepath.Base(child.Filename)
+		files = append(files, (*embeddedFileInfo)(child))
+	}
+
+	// Sort it by filename (lexical order)
+	sort.Sort(SortByName(files))
+
+	// Return all contents if that's what is requested
+	if n <= 0 {
+		vd.offset = 0
+		return files, nil
+	}
+
+	// If user has requested past the end of our list
+	// return what we can and send an EOF
+	if vd.offset+n >= len(files) {
+		offset := vd.offset
+		vd.offset = 0
+		return files[offset:], io.EOF
+	}
+
+	offset := vd.offset
+	vd.offset += n
+	return files[offset : offset+n], nil
+
+}
+
+func (vd *virtualDir) read(bts []byte) (int, error) {
+	if vd.closed {
+		return 0, &os.PathError{
+			Op:   "read",
+			Path: vd.EmbeddedDir.Filename,
+			Err:  errors.New("bad file descriptor"),
+		}
+	}
+	return 0, &os.PathError{
+		Op:   "read",
+		Path: vd.EmbeddedDir.Filename,
+		Err:  errors.New("is a directory"),
+	}
+}
+
+func (vd *virtualDir) seek(offset int64, whence int) (int64, error) {
+	if vd.closed {
+		return 0, &os.PathError{
+			Op:   "seek",
+			Path: vd.EmbeddedDir.Filename,
+			Err:  errors.New("bad file descriptor"),
+		}
+	}
+	return 0, &os.PathError{
+		Op:   "seek",
+		Path: vd.Filename,
+		Err:  errors.New("is a directory"),
+	}
+}
diff --git a/vendor/github.com/GeertJohan/go.rice/walk.go b/vendor/github.com/GeertJohan/go.rice/walk.go
new file mode 100644
index 00000000..3042aeab
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/walk.go
@@ -0,0 +1,122 @@
+package rice
+
+import (
+	"os"
+	"path/filepath"
+	"sort"
+	"strings"
+)
+
+// Walk is like filepath.Walk()
+// Visit http://golang.org/pkg/path/filepath/#Walk for more information
+func (b *Box) Walk(path string, walkFn filepath.WalkFunc) error {
+
+	pathFile, err := b.Open(path)
+	if err != nil {
+		return err
+	}
+	defer pathFile.Close()
+
+	pathInfo, err := pathFile.Stat()
+	if err != nil {
+		return err
+	}
+
+	if b.IsAppended() || b.IsEmbedded() {
+		return b.walk(path, pathInfo, walkFn)
+	}
+
+	// We don't have any embedded or appended box so use live filesystem mode
+	return filepath.Walk(b.absolutePath+string(os.PathSeparator)+path, func(path string, info os.FileInfo, err error) error {
+
+		// Strip out the box name from the returned paths
+		path = strings.TrimPrefix(path, b.absolutePath+string(os.PathSeparator))
+		return walkFn(path, info, err)
+
+	})
+
+}
+
+// walk recursively descends path.
+// See walk() in $GOROOT/src/pkg/path/filepath/path.go
+func (b *Box) walk(path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
+
+	err := walkFn(path, info, nil)
+	if err != nil {
+		if info.IsDir() && err == filepath.SkipDir {
+			return nil
+		}
+		return err
+	}
+
+	if !info.IsDir() {
+		return nil
+	}
+
+	names, err := b.readDirNames(path)
+	if err != nil {
+		return walkFn(path, info, err)
+	}
+
+	for _, name := range names {
+
+		filename := filepath.Join(path, name)
+		fileObject, err := b.Open(filename)
+		if err != nil {
+			return err
+		}
+		defer fileObject.Close()
+
+		fileInfo, err := fileObject.Stat()
+		if err != nil {
+			if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
+				return err
+			}
+		} else {
+			err = b.walk(filename, fileInfo, walkFn)
+			if err != nil {
+				if !fileInfo.IsDir() || err != filepath.SkipDir {
+					return err
+				}
+			}
+		}
+	}
+
+	return nil
+
+}
+
+// readDirNames reads the directory named by path and returns a sorted list of directory entries.
+// See readDirNames() in $GOROOT/pkg/path/filepath/path.go
+func (b *Box) readDirNames(path string) ([]string, error) {
+
+	f, err := b.Open(path)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	stat, err := f.Stat()
+	if err != nil {
+		return nil, err
+	}
+
+	if !stat.IsDir() {
+		return nil, nil
+	}
+
+	infos, err := f.Readdir(0)
+	if err != nil {
+		return nil, err
+	}
+
+	var names []string
+
+	for _, info := range infos {
+		names = append(names, info.Name())
+	}
+
+	sort.Strings(names)
+	return names, nil
+
+}
-- 
cgit v1.2.3