diff --git a/README.md b/README.md
index edf9859..1706e47 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ To access an array value use the index as the key.
 To get the number of elements in an array or to access a child path, use the '#' character.
 The dot and wildcard characters can be escaped with '\'.
 
-```
+```json
 {
   "name": {"first": "Tom", "last": "Anderson"},
   "age":37,
@@ -93,16 +93,6 @@ string, for JSON string literals
 nil, for JSON null
 ```
 
-To get the Go value call the `Value()` method:
-
-
-```go
-result.Value()  // interface{} which may be nil, string, float64, or bool
-
-// Or just get the value in one step.
-gjson.Get(json, "name.last").Value()
-```
-
 To directly access the value:
 
 ```go
@@ -113,6 +103,30 @@ result.Raw     // holds the raw json
 result.Multi   // holds nested array values
 ```
 
+There are a variety of handy functions that work on a result:
+
+```go
+result.Value() interface{}
+result.Int() int64
+result.Float() float64
+result.String() string
+result.Bool() bool
+result.Array() []gjson.Result
+result.Map() map[string]gjson.Result
+result.Get(path string) Result
+```
+
+The `result.Value()` function returns an `interface{}` which requires type assertion and is one of the following Go types:
+
+```go
+boolean >> bool
+number  >> float64
+string  >> string
+null    >> nil
+array   >> []interface{}
+object  >> map[string]interface{}
+```
+
 ## Get nested array values
 
 Suppose you want all the last names from the following json:
@@ -138,11 +152,23 @@ You would use the path "programmers.#.lastName" like such:
 
 ```go
 result := gjson.Get(json, "programmers.#.lastName")
-for _,name := range result.Multi {
+for _,name := range result.Array() {
 	println(name.String())
 }
 ```
 
+## Simple Parse and Get
+
+There's a `Parse(json)` function that will do a simple parse, and `result.Get(path)` that will search a result.
+
+For example, all of these will return the same result:
+
+```go
+Parse(json).Get("name").Get("last")
+Get("name").Get("last")
+Get("name.last")
+```
+
 ## Check for the existence of a value
 
 Sometimes you may want to see if the value actually existed in the json document.
diff --git a/gjson.go b/gjson.go
index 8001db3..a4a9f75 100644
--- a/gjson.go
+++ b/gjson.go
@@ -19,8 +19,6 @@ const (
 	True
 	// JSON is a raw block of JSON
 	JSON
-	// Multi is a subset of results
-	Multi
 )
 
 // Result represents a json value that is returned from Get().
@@ -33,8 +31,6 @@ type Result struct {
 	Str string
 	// Num is the json number
 	Num float64
-	// Multi is the subset of results
-	Multi []Result
 }
 
 // String returns a string representation of the value.
@@ -48,15 +44,6 @@ func (t Result) String() string {
 		return strconv.FormatFloat(t.Num, 'f', -1, 64)
 	case String:
 		return t.Str
-	case Multi:
-		var str string
-		for i, res := range t.Multi {
-			if i > 0 {
-				str += ","
-			}
-			str += res.String()
-		}
-		return str
 	case JSON:
 		return t.Raw
 	case True:
@@ -64,6 +51,316 @@ func (t Result) String() string {
 	}
 }
 
+// Bool returns an boolean representation.
+func (t Result) Bool() bool {
+	switch t.Type {
+	default:
+		return false
+	case True:
+		return true
+	case String:
+		return t.Str != "" && t.Str != "0"
+	case Number:
+		return t.Num != 0
+	}
+}
+
+// Int returns an integer representation.
+func (t Result) Int() int64 {
+	switch t.Type {
+	default:
+		return 0
+	case True:
+		return 1
+	case String:
+		n, _ := strconv.ParseInt(t.Str, 10, 64)
+		return n
+	case Number:
+		return int64(t.Num)
+	}
+}
+
+// Float returns an float64 representation.
+func (t Result) Float() float64 {
+	switch t.Type {
+	default:
+		return 0
+	case True:
+		return 1
+	case String:
+		n, _ := strconv.ParseFloat(t.Str, 64)
+		return n
+	case Number:
+		return t.Num
+	}
+}
+
+// Array returns back an array of children. The result must be a JSON array.
+func (t Result) Array() []Result {
+	if t.Type != JSON {
+		return nil
+	}
+	a, _, _ := t.arrayOrMap('[')
+	return a
+}
+
+//  Map returns back an map of children. The result should be a JSON array.
+func (t Result) Map() map[string]Result {
+	if t.Type != JSON {
+		return map[string]Result{}
+	}
+	_, o, _ := t.arrayOrMap('{')
+	return o
+}
+
+// Get searches result for the specified path.
+// The result should be a JSON array or object.
+func (t Result) Get(path string) Result {
+	return Get(t.Raw, path)
+}
+
+func (t Result) arrayOrMap(vc byte) ([]Result, map[string]Result, byte) {
+	var a = []Result{}
+	var o = map[string]Result{}
+	var json = t.Raw
+	var i int
+	var value Result
+	var count int
+	var key Result
+	if vc == 0 {
+		for ; i < len(json); i++ {
+			if json[i] == '{' || json[i] == '[' {
+				vc = json[i]
+				i++
+				break
+			}
+			if json[i] > ' ' {
+				goto end
+			}
+		}
+	} else {
+		for ; i < len(json); i++ {
+			if json[i] == vc {
+				i++
+				break
+			}
+			if json[i] > ' ' {
+				goto end
+			}
+		}
+	}
+	for ; i < len(json); i++ {
+		if json[i] <= ' ' {
+			continue
+		}
+		// get next value
+		if json[i] == ']' || json[i] == '}' {
+			break
+		}
+		switch json[i] {
+		default:
+			if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' {
+				value.Type = Number
+				value.Raw, value.Num = tonum(json[i:])
+			} else {
+				continue
+			}
+		case '{', '[':
+			value.Type = JSON
+			value.Raw = squash(json[i:])
+		case 'n':
+			value.Type = Null
+			value.Raw = tolit(json[i:])
+		case 't':
+			value.Type = True
+			value.Raw = tolit(json[i:])
+		case 'f':
+			value.Type = False
+			value.Raw = tolit(json[i:])
+		case '"':
+			value.Type = String
+			value.Raw, value.Str = tostr(json[i:])
+		}
+		i += len(value.Raw) - 1
+
+		if vc == '{' {
+			if count%2 == 0 {
+				key = value
+			} else {
+				o[key.Str] = value
+			}
+			count++
+		} else {
+			a = append(a, value)
+		}
+	}
+end:
+	return a, o, vc
+}
+
+// Parse parses the json and returns a result
+func Parse(json string) Result {
+	var value Result
+	for i := 0; i < len(json); i++ {
+		if json[i] <= ' ' {
+			continue
+		}
+		switch json[i] {
+		default:
+			if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' {
+				value.Type = Number
+				value.Raw, value.Num = tonum(json[i:])
+			} else {
+				return Result{}
+			}
+		case '{', '[':
+			value.Type = JSON
+			value.Raw = json[i:]
+			// we just trim the tail end
+			for value.Raw[len(value.Raw)-1] <= ' ' {
+				value.Raw = value.Raw[:len(value.Raw)-1]
+			}
+		case 'n':
+			value.Type = Null
+			value.Raw = tolit(json[i:])
+		case 't':
+			value.Type = True
+			value.Raw = tolit(json[i:])
+		case 'f':
+			value.Type = False
+			value.Raw = tolit(json[i:])
+		case '"':
+			value.Type = String
+			value.Raw, value.Str = tostr(json[i:])
+		}
+		break
+	}
+	return value
+}
+
+func squash(json string) string {
+	// expects that the lead character is a '[' or '{'
+	// squash the value, ignoring all nested arrays and objects.
+	// the first '[' or '{' has already been read
+	depth := 1
+	for i := 1; i < len(json); i++ {
+		if json[i] >= '"' && json[i] <= '}' {
+			switch json[i] {
+			case '"':
+				i++
+				s2 := i
+				for ; i < len(json); i++ {
+					if json[i] > '\\' {
+						continue
+					}
+					if json[i] == '"' {
+						// look for an escaped slash
+						if json[i-1] == '\\' {
+							n := 0
+							for j := i - 2; j > s2-1; j-- {
+								if json[j] != '\\' {
+									break
+								}
+								n++
+							}
+							if n%2 == 0 {
+								continue
+							}
+						}
+						break
+					}
+				}
+			case '{', '[':
+				depth++
+			case '}', ']':
+				depth--
+				if depth == 0 {
+					return json[:i+1]
+				}
+			}
+		}
+	}
+	return json
+}
+
+func tonum(json string) (raw string, num float64) {
+	for i := 1; i < len(json); i++ {
+		// less than dash might have valid characters
+		if json[i] <= '-' {
+			if json[i] <= ' ' || json[i] == ',' {
+				// break on whitespace and comma
+				raw = json[:i]
+				num, _ = strconv.ParseFloat(raw, 64)
+				return
+			}
+			// could be a '+' or '-'. let's assume so.
+			continue
+		}
+		if json[i] < ']' {
+			// probably a valid number
+			continue
+		}
+		if json[i] == 'e' || json[i] == 'E' {
+			// allow for exponential numbers
+			continue
+		}
+		// likely a ']' or '}'
+		raw = json[:i]
+		num, _ = strconv.ParseFloat(raw, 64)
+		return
+	}
+	raw = json
+	num, _ = strconv.ParseFloat(raw, 64)
+	return
+}
+
+func tolit(json string) (raw string) {
+	for i := 1; i < len(json); i++ {
+		if json[i] <= 'a' || json[i] >= 'z' {
+			return json[:i]
+		}
+	}
+	return json
+}
+
+func tostr(json string) (raw string, str string) {
+	// expects that the lead character is a '"'
+	for i := 1; i < len(json); i++ {
+		if json[i] > '\\' {
+			continue
+		}
+		if json[i] == '"' {
+			return json[:i+1], json[1:i]
+		}
+		if json[i] == '\\' {
+			i++
+			for ; i < len(json); i++ {
+				if json[i] > '\\' {
+					continue
+				}
+				if json[i] == '"' {
+					// look for an escaped slash
+					if json[i-1] == '\\' {
+						n := 0
+						for j := i - 2; j > 0; j-- {
+							if json[j] != '\\' {
+								break
+							}
+							n++
+						}
+						if n%2 == 0 {
+							continue
+						}
+					}
+					break
+				}
+			}
+			return json[:i+1], unescape(json[1:i])
+		}
+	}
+	return json, json[1:]
+}
+
 // Exists returns true if value exists.
 //
 //  if gjson.Get(json, "name.last").Exists(){
@@ -92,17 +389,26 @@ func (t Result) Value() interface{} {
 		return false
 	case Number:
 		return t.Num
-	case Multi:
-		var res = make([]interface{}, len(t.Multi))
-		for i, v := range t.Multi {
-			res[i] = v.Value()
-		}
-		return res
 	case JSON:
-		return t.Raw
+		a, o, vc := t.arrayOrMap(0)
+		if vc == '{' {
+			var m = map[string]interface{}{}
+			for k, v := range o {
+				m[k] = v.Value()
+			}
+			return m
+		} else if vc == '[' {
+			var m = make([]interface{}, 0, len(a))
+			for _, v := range a {
+				m = append(m, v.Value())
+			}
+			return m
+		}
+		return nil
 	case True:
 		return true
 	}
+
 }
 
 type part struct {
@@ -518,6 +824,9 @@ proc_val:
 				// the first double-quote has already been read
 				s = i
 				for ; i < len(json); i++ {
+					if json[i] > '\\' {
+						continue
+					}
 					if json[i] == '"' {
 						value.Raw = json[s-1 : i+1]
 						value.Str = json[s:i]
@@ -598,14 +907,19 @@ proc_val:
 		case '}', ']':
 			if arrch && parts[depth-1].key == "#" {
 				if alogok {
-					result := Result{Type: Multi}
+					var jsons = make([]byte, 0, 64)
+					jsons = append(jsons, '[')
 					for j := 0; j < len(alog); j++ {
 						res := Get(json[alog[j]:], alogkey)
 						if res.Exists() {
-							result.Multi = append(result.Multi, res)
+							if j > 0 {
+								jsons = append(jsons, ',')
+							}
+							jsons = append(jsons, []byte(res.Raw)...)
 						}
 					}
-					return result
+					jsons = append(jsons, ']')
+					return Result{Type: JSON, Raw: string(jsons)}
 				} else {
 					return Result{Type: Number, Num: float64(f.count)}
 				}
@@ -689,7 +1003,7 @@ func unescape(json string) string { //, error) {
 // The caseSensitive paramater is used when the tokens are Strings.
 // The order when comparing two different type is:
 //
-//  Null < False < Number < String < True < JSON < Multi
+//  Null < False < Number < String < True < JSON
 //
 func (t Result) Less(token Result, caseSensitive bool) bool {
 	if t.Type < token.Type {
@@ -707,17 +1021,6 @@ func (t Result) Less(token Result, caseSensitive bool) bool {
 	if t.Type == Number {
 		return t.Num < token.Num
 	}
-	if t.Type == Multi {
-		for i := 0; i < len(t.Multi) && i < len(token.Multi); i++ {
-			if t.Multi[i].Less(token.Multi[i], caseSensitive) {
-				return true
-			}
-			if token.Multi[i].Less(t.Multi[i], caseSensitive) {
-				return false
-			}
-		}
-		return len(t.Multi) < len(token.Multi)
-	}
 	return t.Raw < token.Raw
 }
 
diff --git a/gjson_test.go b/gjson_test.go
index 0e85caa..15dfa24 100644
--- a/gjson_test.go
+++ b/gjson_test.go
@@ -116,32 +116,64 @@ var basicJSON = `{"age":100, "name":{"here":"B\\\"R"},
     	        "firstName": "Elliotte", 
     	        "lastName": "Harold", 
     	        "email": "cccc"
-    	    }
+    	    },
+			{
+				"firstName": 1002.3
+			}
     	]
 	}
 }`
 
 func TestBasic(t *testing.T) {
+	var mtok Result
+	mtok = Get(basicJSON, "loggy")
+	if mtok.Type != JSON {
+		t.Fatalf("expected %v, got %v", JSON, mtok.Type)
+	}
+	if len(mtok.Map()) != 1 {
+		t.Fatalf("expected %v, got %v", 1, len(mtok.Map()))
+	}
+	programmers := mtok.Map()["programmers"]
+	if programmers.Array()[1].Map()["firstName"].Str != "Jason" {
+		t.Fatalf("expected %v, got %v", "Jason", mtok.Map()["programmers"].Array()[1].Map()["firstName"].Str)
+	}
+
+	if Parse(basicJSON).Get("loggy.programmers").Get("1").Get("firstName").Str != "Jason" {
+		t.Fatalf("expected %v, got %v", "Jason", Parse(basicJSON).Get("loggy.programmers").Get("1").Get("firstName").Str)
+	}
 	var token Result
-	mtok := Get(basicJSON, "loggy.programmers.#.firstName")
-	if mtok.Type != Multi {
-		t.Fatal("expected %v, got %v", Multi, mtok.Type)
+	if token = Parse("-102"); token.Num != -102 {
+		t.Fatal("expected %v, got %v", -102, token.Num)
 	}
-	if len(mtok.Multi) != 3 {
-		t.Fatalf("expected 3, got %v", len(mtok.Multi))
+	if token = Parse("102"); token.Num != 102 {
+		t.Fatal("expected %v, got %v", 102, token.Num)
 	}
-	for i, ex := range []string{"Brett", "Jason", "Elliotte"} {
-		if mtok.Multi[i].String() != ex {
-			t.Fatalf("expected '%v', got '%v'", ex, mtok.Multi[i].String())
+	if token = Parse("102.2"); token.Num != 102.2 {
+		t.Fatal("expected %v, got %v", 102.2, token.Num)
+	}
+	if token = Parse(`"hello"`); token.Str != "hello" {
+		t.Fatal("expected %v, got %v", "hello", token.Str)
+	}
+	if token = Parse(`"\"he\nllo\""`); token.Str != "\"he\nllo\"" {
+		t.Fatal("expected %v, got %v", "\"he\nllo\"", token.Str)
+	}
+	mtok = Get(basicJSON, "loggy.programmers.#.firstName")
+	if len(mtok.Array()) != 4 {
+		t.Fatalf("expected 4, got %v", len(mtok.Array()))
+	}
+	for i, ex := range []string{"Brett", "Jason", "Elliotte", "1002.3"} {
+		if mtok.Array()[i].String() != ex {
+			t.Fatalf("expected '%v', got '%v'", ex, mtok.Array()[i].String())
 		}
 	}
 	mtok = Get(basicJSON, "loggy.programmers.#.asd")
-	if mtok.Type != Multi {
-		t.Fatal("expected %v, got %v", Multi, mtok.Type)
+	if mtok.Type != JSON {
+		t.Fatal("expected %v, got %v", JSON, mtok.Type)
 	}
-	if len(mtok.Multi) != 0 {
-		t.Fatalf("expected 0, got %v", len(mtok.Multi))
+	if len(mtok.Array()) != 0 {
+		t.Fatalf("expected 0, got %v", len(mtok.Array()))
 	}
+
 	if Get(basicJSON, "items.3.tags.#").Num != 3 {
 		t.Fatalf("expected 3, got %v", Get(basicJSON, "items.3.tags.#").Num)
 	}
@@ -201,13 +233,19 @@ func TestBasic(t *testing.T) {
 	if token.String() != `{"what is a wren?":"a bird"}` {
 		t.Fatal("expecting '"+`{"what is a wren?":"a bird"}`+"'", "got", token.String())
 	}
-	_ = token.Value().(string)
+	_ = token.Value().(map[string]interface{})
 
 	if Get(basicJSON, "").Value() != nil {
 		t.Fatal("should be nil")
 	}
 
 	Get(basicJSON, "vals.hello")
+
+	mm := Parse(basicJSON).Value().(map[string]interface{})
+	fn := mm["loggy"].(map[string]interface{})["programmers"].([]interface{})[1].(map[string]interface{})["firstName"].(string)
+	if fn != "Jason" {
+		t.Fatalf("expecting %v, got %v", "Jason", fn)
+	}
 }
 
 func TestUnescape(t *testing.T) {