func (m *Message) Dump() (resp string) {
	var keys []string
	for k := range m.Headers {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		resp += fmt.Sprintf("%s: %s\r\n", k, m.Headers[k])
	}
	resp += fmt.Sprintf("BODY: %v\r\n", string(m.Body))
	return
}
Dump - Will return message prepared to be dumped out. It's like prettify message for output
package goesl
import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/textproto"
	"net/url"
	"sort"
	"strconv"
	"strings"
)
type Message struct {
	Headers map[string]string
	Body    []byte
	r  *bufio.Reader
	tr *textproto.Reader
}
func (m *Message) String() string {
	return fmt.Sprintf("%v body=%s", m.Headers, m.Body)
}
func (m *Message) GetCallUUID() string {
	return m.GetHeader("Caller-Unique-Id")
}
func (m *Message) GetHeader(key string) string {
	return m.Headers[key]
}
func (m *Message) Parse() error {
	cmr, err := m.tr.ReadMIMEHeader()
	if err != nil && err.Error() != "EOF" {
		Error(ECouldNotReadMIMEHeaders, err)
		return err
	}
	if cmr.Get("Content-Type") == "" {
		Debug("Not accepting message because of empty content type. Just whatever with it ...")
		return fmt.Errorf("Parse EOF")
	}
	if lv := cmr.Get("Content-Length"); lv != "" {
		l, err := strconv.Atoi(lv)
		if err != nil {
			Error(EInvalidContentLength, err)
			return err
		}
		m.Body = make([]byte, l)
		if _, err := io.ReadFull(m.r, m.Body); err != nil {
			Error(ECouldNotReadyBody, err)
			return err
		}
	}
	msgType := cmr.Get("Content-Type")
	Debug("Got message content (type: %s). Searching if we can handle it ...", msgType)
	if !StringInSlice(msgType, AvailableMessageTypes) {
		return fmt.Errorf(EUnsupportedMessageType, msgType, AvailableMessageTypes)
	}
	if msgType != "text/event-json" {
		for k, v := range cmr {
			m.Headers[k] = v[0]
			if strings.Contains(v[0], "%") {
				m.Headers[k], err = url.QueryUnescape(v[0])
				if err != nil {
					Error(ECouldNotDecode, err)
					continue
				}
			}
		}
	}
	switch msgType {
	case "text/disconnect-notice":
		for k, v := range cmr {
			Debug("Message (header: %s) -> (value: %v)", k, v)
		}
	case "command/reply":
		reply := cmr.Get("Reply-Text")
		if strings.Contains(reply, "-ERR") {
			return fmt.Errorf(EUnsuccessfulReply, reply[5:])
		}
	case "api/response":
		if strings.Contains(string(m.Body), "-ERR") {
			return fmt.Errorf(EUnsuccessfulReply, string(m.Body)[5:])
		}
	case "text/event-json":
		var decoded map[string]interface{}
		if err := json.Unmarshal(m.Body, &decoded); err != nil {
			return err
		}
		for k, v := range decoded {
			switch v.(type) {
			case string:
				m.Headers[k] = v.(string)
			default:
				Warning("Removed non-string property (%s)", k)
			}
		}
		if v, _ := m.Headers["_body"]; v != "" {
			m.Body = []byte(v)
			delete(m.Headers, "_body")
		} else {
			m.Body = []byte("")
		}
	case "text/event-plain":
		r := bufio.NewReader(bytes.NewReader(m.Body))
		tr := textproto.NewReader(r)
		emh, err := tr.ReadMIMEHeader()
		if err != nil {
			return fmt.Errorf(ECouldNotReadMIMEHeaders, err)
		}
		if vl := emh.Get("Content-Length"); vl != "" {
			length, err := strconv.Atoi(vl)
			if err != nil {
				Error(EInvalidContentLength, err)
				return err
			}
			m.Body = make([]byte, length)
			if _, err = io.ReadFull(r, m.Body); err != nil {
				Error(ECouldNotReadyBody, err)
				return err
			}
		}
	}
	return nil
}