func GetObj(overseer Overseer, w http.ResponseWriter, r *http.Request, pointer interface{}) error {
	val, err := overseer.Get(w, r)
	if err != nil {
		return errors.Wrap(err, "unable to get session")
	}
	var sess session
	err = json.Unmarshal([]byte(val), &sess)
	if err != nil {
		return errors.Wrap(err, "unable to unmarshal session object")
	}
	err = json.Unmarshal(*sess.Value, pointer)
	return errors.Wrap(err, "unable to unmarshal session value into pointer")
}
GetObj is a JSON helper used for retrieving object or variable session values.
GetObj unmarshals the session value into the pointer pointed to by pointer.
package abcsessions
import (
	"encoding/json"
	"net/http"
	"time"
	"github.com/friendsofgo/errors"
)
type session struct {
	Value *json.RawMessage
	Flash map[string]*json.RawMessage
}
type Storer interface {
	All() (keys []string, err error)
	Get(key string) (value string, err error)
	Set(key, value string) error
	Del(key string) error
	ResetExpiry(key string) error
}
type Overseer interface {
	Resetter
	Get(w http.ResponseWriter, r *http.Request) (value string, err error)
	Set(w http.ResponseWriter, r *http.Request, value string) error
	Del(w http.ResponseWriter, r *http.Request) error
	Regenerate(w http.ResponseWriter, r *http.Request) error
	SessionID(w http.ResponseWriter, r *http.Request) (id string, err error)
}
type Resetter interface {
	ResetExpiry(w http.ResponseWriter, r *http.Request) error
	ResetMiddleware(next http.Handler) http.Handler
	MiddlewareWithReset(next http.Handler) http.Handler
}
type timer interface {
	Stop() bool
	Reset(time.Duration) bool
}
type noSessionInterface interface {
	NoSession()
}
type noMapKeyInterface interface {
	NoMapKey()
}
type errNoSession struct{}
type errNoMapKey struct{}
func (errNoSession) NoSession() {}
func (errNoMapKey) NoMapKey()   {}
func (errNoSession) Error() string {
	return "session does not exist"
}
func (errNoMapKey) Error() string {
	return "session map key does not exist"
}
func IsNoSessionError(err error) bool {
	_, ok := err.(noSessionInterface)
	if ok {
		return ok
	}
	_, ok = errors.Cause(err).(noSessionInterface)
	return ok
}
func IsNoMapKeyError(err error) bool {
	_, ok := err.(noMapKeyInterface)
	if ok {
		return ok
	}
	_, ok = errors.Cause(err).(noMapKeyInterface)
	return ok
}
var timerTestHarness = func(d time.Duration) (timer, <-chan time.Time) {
	t := time.NewTimer(d)
	return t, t.C
}
func validKey(key string) bool {
	if len(key) != 36 {
		return false
	}
	dashPos := []int{8, 13, 18, 23}
	for i := 0; i < len(key); i++ {
		atDashPos := false
		for _, pos := range dashPos {
			if i == pos {
				atDashPos = true
				break
			}
		}
		if atDashPos == true {
			if key[i] != '-' {
				return false
			}
			continue
		}
		if key[i] < 48 || (key[i] > 57 && key[i] < 97) || key[i] > 102 {
			return false
		}
	}
	return true
}
func Set(overseer Overseer, w http.ResponseWriter, r *http.Request, key string, value string) error {
	var sess session
	sessMap := make(map[string]string)
	val, err := overseer.Get(w, r)
	if err != nil && !IsNoSessionError(err) {
		return errors.Wrap(err, "unable to get session")
	}
	if !IsNoSessionError(err) {
		err = json.Unmarshal([]byte(val), &sess)
		if err != nil {
			return errors.Wrap(err, "unable to unmarshal session object")
		}
		if sess.Value != nil {
			err = json.Unmarshal(*sess.Value, &sessMap)
			if err != nil {
				return errors.Wrap(err, "unable to unmarshal session map value")
			}
		}
	}
	sessMap[key] = value
	mv, err := json.Marshal(sessMap)
	if err != nil {
		return errors.Wrap(err, "unable to marshal session map value")
	}
	sess.Value = (*json.RawMessage)(&mv)
	ret, err := json.Marshal(sess)
	if err != nil {
		return errors.Wrap(err, "unable to marshal session object")
	}
	return overseer.Set(w, r, string(ret))
}
func Get(overseer Overseer, w http.ResponseWriter, r *http.Request, key string) (string, error) {
	val, err := overseer.Get(w, r)
	if err != nil {
		return "", errors.Wrap(err, "unable to get session")
	}
	var sess session
	err = json.Unmarshal([]byte(val), &sess)
	if err != nil {
		return "", errors.Wrap(err, "unable to unmarshal session object")
	}
	var sessMap map[string]string
	err = json.Unmarshal(*sess.Value, &sessMap)
	if err != nil {
		return "", errors.Wrap(err, "unable to unmarshal session map value")
	}
	mapVal, ok := sessMap[key]
	if !ok {
		return "", errNoMapKey{}
	}
	return mapVal, nil
}
func Del(overseer Overseer, w http.ResponseWriter, r *http.Request, key string) error {
	val, err := overseer.Get(w, r)
	if err != nil {
		return errors.Wrap(err, "unable to get session")
	}
	var sess session
	err = json.Unmarshal([]byte(val), &sess)
	if err != nil {
		return errors.Wrap(err, "unable to unmarshal session object")
	}
	var sessMap map[string]string
	err = json.Unmarshal(*sess.Value, &sessMap)
	if err != nil {
		return errors.Wrap(err, "unable to unmarshal session map value")
	}
	delete(sessMap, key)
	mv, err := json.Marshal(sessMap)
	if err != nil {
		return errors.Wrap(err, "unable to marshal session map value")
	}
	sess.Value = (*json.RawMessage)(&mv)
	ret, err := json.Marshal(sess)
	if err != nil {
		return errors.Wrap(err, "unable to marshal session object")
	}
	return overseer.Set(w, r, string(ret))
}
func SetObj(overseer Overseer, w http.ResponseWriter, r *http.Request, value interface{}) error {
	val, err := overseer.Get(w, r)
	if err != nil && !IsNoSessionError(err) {
		return errors.Wrap(err, "unable to get session")
	}
	var sess session
	if !IsNoSessionError(err) {
		err = json.Unmarshal([]byte(val), &sess)
		if err != nil {
			return errors.Wrap(err, "unable to unmarshal session object")
		}
	}
	mv, err := json.Marshal(value)
	if err != nil {
		return errors.Wrap(err, "unable to marshal value")
	}
	sess.Value = (*json.RawMessage)(&mv)
	ret, err := json.Marshal(sess)
	if err != nil {
		return errors.Wrap(err, "unable to marshal session object")
	}
	return overseer.Set(w, r, string(ret))
}