func (e *Envelope) MarshalRST(r *http.Request) (string, []byte, error) {
	return Marshal(e.projection, r)
}
MarshalRST marshals projection.
package rst
import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"time"
	"github.com/gorilla/context"
	gorillaMux "github.com/gorilla/mux"
)
const rfc1123 = "Mon, 02 Jan 2006 15:04:05 GMT"
const (
	Options = "OPTIONS"
	Head    = "HEAD"
	Get     = "GET"
	Patch   = "PATCH"
	Put     = "PUT"
	Post    = "POST"
	Delete  = "DELETE"
)
type RouteVars map[string]string
func (rv RouteVars) Get(key string) string {
	value, _ := rv[key]
	return value
}
type responseWriter struct {
	http.ResponseWriter
	wfl io.Writer
}
func (rw *responseWriter) flush() {
	if rw.wfl == nil {
		return
	}
	if compressor, ok := rw.wfl.(compressor); ok {
		compressor.Flush()
		return
	}
	if flusher, ok := rw.wfl.(http.Flusher); ok {
		flusher.Flush()
		return
	}
}
func (rw *responseWriter) Write(b []byte) (int, error) {
	n, err := compress(rw.ResponseWriter.Header().Get("Content-Encoding"), rw.ResponseWriter, b)
	if err == errUnknownCompressionFormat {
		return rw.ResponseWriter.Write(b)
	}
	return n, err
}
func newResponseWriter(w http.ResponseWriter) *responseWriter {
	return &responseWriter{ResponseWriter: w}
}
const varsKey = "__rst__vars"
func getVars(r *http.Request) (vars RouteVars) {
	if v := context.Get(r, varsKey); v != nil {
		vars = v.(RouteVars)
	}
	return vars
}
func setVars(r *http.Request, vars RouteVars) {
	context.Set(r, varsKey, vars)
}
func delVars(r *http.Request) {
	context.Clear(r)
}
type Mux struct {
	Debug     bool  
	Logger    *log.Logger
	header    http.Header
	ac        *AccessControlResponse
	m         *gorillaMux.Router
	endpoints map[string]mapEndpoint
}
func NewMux() *Mux {
	s := &Mux{
		Logger:    log.New(os.Stdout, "rst: ", log.LstdFlags),
		header:    make(http.Header),
		m:         gorillaMux.NewRouter(),
		endpoints: make(map[string]mapEndpoint),
	}
	return s
}
func (s *Mux) Header() http.Header {
	return s.header
}
func (s *Mux) SetCORSPolicy(ac *AccessControlResponse) {
	s.ac = ac
}
func (s *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			reason := fmt.Sprintf("%s", err)  
			if !s.Debug {
				t := InternalServerError(reason, "", true)
				s.Logger.Println(t.String())
				reason = http.StatusText(http.StatusInternalServerError)
			}
			InternalServerError(reason, "", s.Debug).ServeHTTP(w, r)
		}
	}()
	for key, values := range s.header {
		for i, value := range values {
			if i == 0 {
				w.Header().Set(key, value)
			} else {
				w.Header().Add(key, value)
			}
		}
	}
	match := s.match(r)
	if match == nil || match.Handler == nil {
		NotFound().ServeHTTP(w, r)
		return
	}
	setVars(r, RouteVars(match.Vars))
	defer delVars(r)
	if s.ac != nil {
		if handler, valid := match.Handler.(*endpointHandler); valid {
			newAccessControlHandler(handler.endpoint, s.ac).ServeHTTP(w, r)
		} else {
			newAccessControlHandler(nil, s.ac).ServeHTTP(w, r)
		}
	}
	match.Handler.ServeHTTP(newResponseWriter(w), r)
}
func (s *Mux) HandleEndpoint(pattern string, endpoint Endpoint) {
	s.Handle(pattern, EndpointHandler(endpoint))
}
func (s *Mux) Handle(pattern string, handler http.Handler) {
	s.m.Handle(pattern, handler)
}
func (s *Mux) handleMethod(pattern string, method string, handler http.Handler) {
	if _, ok := s.endpoints[pattern]; !ok {
		s.endpoints[pattern] = make(mapEndpoint)
		s.m.Handle(pattern, EndpointHandler(s.endpoints[pattern]))
	}
	s.endpoints[pattern][method] = handler
}
func (s *Mux) Get(pattern string, handler GetFunc) {
	s.handleMethod(pattern, Get, handler)
}
func (s *Mux) Post(pattern string, handler PostFunc) {
	s.handleMethod(pattern, Post, handler)
}
func (s *Mux) Put(pattern string, handler PutFunc) {
	s.handleMethod(pattern, Put, handler)
}
func (s *Mux) Patch(pattern string, handler PatchFunc) {
	s.handleMethod(pattern, Put, handler)
}
func (s *Mux) Delete(pattern string, handler DeleteFunc) {
	s.handleMethod(pattern, Delete, handler)
}
func (s *Mux) match(r *http.Request) *gorillaMux.RouteMatch {
	var match gorillaMux.RouteMatch
	if !s.m.Match(r, &match) {
		return nil
	}
	return &match
}
type mapEndpoint map[string]http.Handler
func (e mapEndpoint) allowedMethods() []string {
	var methods []string
	for method := range e {
		methods = append(methods, method)
	}
	if _, ok := e[Get]; ok {
		methods = append(methods, Head)
	}
	return methods
}
func (e mapEndpoint) validateMethod(r *http.Request) error {
	if _, ok := e[r.Method]; !ok {
		return MethodNotAllowed(r.Method, e.allowedMethods())
	}
	return nil
}
func (e mapEndpoint) Get(vars RouteVars, r *http.Request) (Resource, error) {
	if err := e.validateMethod(r); err != nil {
		return nil, err
	}
	fn := e[r.Method].(GetFunc)
	return fn(vars, r)
}
func (e mapEndpoint) Post(vars RouteVars, r *http.Request) (Resource, string, error) {
	if err := e.validateMethod(r); err != nil {
		return nil, "", err
	}
	fn := e[r.Method].(PostFunc)
	return fn(vars, r)
}
func (e mapEndpoint) Put(vars RouteVars, r *http.Request) (Resource, error) {
	if err := e.validateMethod(r); err != nil {
		return nil, err
	}
	fn := e[r.Method].(PutFunc)
	return fn(vars, r)
}
func (e mapEndpoint) Patch(vars RouteVars, r *http.Request) (Resource, error) {
	if err := e.validateMethod(r); err != nil {
		return nil, err
	}
	fn := e[r.Method].(PatchFunc)
	return fn(vars, r)
}
func (e mapEndpoint) Delete(vars RouteVars, r *http.Request) error {
	if err := e.validateMethod(r); err != nil {
		return nil
	}
	fn := e[r.Method].(DeleteFunc)
	return fn(vars, r)
}
type Envelope struct {
	projection   interface{}
	lastModified time.Time
	etag         string
	ttl          time.Duration
	header       http.Header
}
func (e *Envelope) Header() http.Header {
	return e.header
}
func (e *Envelope) Projection() interface{} {
	return e.projection
}
func (e *Envelope) TTL() time.Duration {
	return e.ttl
}
func (e *Envelope) LastModified() time.Time {
	return e.lastModified
}
func (e *Envelope) ETag() string {
	return e.etag
}