diff --git a/query/pb/graphresponse.pb.go b/query/pb/graphresponse.pb.go
index 75212c7fb9da34453e5d1ca815a2ae6c4339479e..2fd972a71b0eac8ffc8b8f4081bc82d4f4722c92 100644
--- a/query/pb/graphresponse.pb.go
+++ b/query/pb/graphresponse.pb.go
@@ -9,8 +9,6 @@ It is generated from these files:
 	graphresponse.proto
 
 It has these top-level messages:
-	UidList
-	Result
 	GraphRequest
 	GraphResponse
 */
@@ -34,32 +32,6 @@ var _ = math.Inf
 // is compatible with the proto package it is being compiled against.
 const _ = proto.ProtoPackageIsVersion1
 
-type UidList struct {
-	Uids []uint64 `protobuf:"varint,1,rep,name=uids" json:"uids,omitempty"`
-}
-
-func (m *UidList) Reset()                    { *m = UidList{} }
-func (m *UidList) String() string            { return proto.CompactTextString(m) }
-func (*UidList) ProtoMessage()               {}
-func (*UidList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-type Result struct {
-	Values    [][]byte   `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
-	Uidmatrix []*UidList `protobuf:"bytes,2,rep,name=uidmatrix" json:"uidmatrix,omitempty"`
-}
-
-func (m *Result) Reset()                    { *m = Result{} }
-func (m *Result) String() string            { return proto.CompactTextString(m) }
-func (*Result) ProtoMessage()               {}
-func (*Result) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
-
-func (m *Result) GetUidmatrix() []*UidList {
-	if m != nil {
-		return m.Uidmatrix
-	}
-	return nil
-}
-
 type GraphRequest struct {
 	Query string `protobuf:"bytes,1,opt,name=query" json:"query,omitempty"`
 }
@@ -67,30 +39,22 @@ type GraphRequest struct {
 func (m *GraphRequest) Reset()                    { *m = GraphRequest{} }
 func (m *GraphRequest) String() string            { return proto.CompactTextString(m) }
 func (*GraphRequest) ProtoMessage()               {}
-func (*GraphRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+func (*GraphRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 
 type GraphResponse struct {
-	Attribute string           `protobuf:"bytes,1,opt,name=attribute" json:"attribute,omitempty"`
-	Result    *Result          `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
-	Query     *UidList         `protobuf:"bytes,3,opt,name=query" json:"query,omitempty"`
-	Children  []*GraphResponse `protobuf:"bytes,4,rep,name=children" json:"children,omitempty"`
+	Attribute string            `protobuf:"bytes,1,opt,name=attribute" json:"attribute,omitempty"`
+	Values    map[string][]byte `protobuf:"bytes,2,rep,name=values" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	Children  []*GraphResponse  `protobuf:"bytes,3,rep,name=children" json:"children,omitempty"`
 }
 
 func (m *GraphResponse) Reset()                    { *m = GraphResponse{} }
 func (m *GraphResponse) String() string            { return proto.CompactTextString(m) }
 func (*GraphResponse) ProtoMessage()               {}
-func (*GraphResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
-
-func (m *GraphResponse) GetResult() *Result {
-	if m != nil {
-		return m.Result
-	}
-	return nil
-}
+func (*GraphResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
 
-func (m *GraphResponse) GetQuery() *UidList {
+func (m *GraphResponse) GetValues() map[string][]byte {
 	if m != nil {
-		return m.Query
+		return m.Values
 	}
 	return nil
 }
@@ -103,8 +67,6 @@ func (m *GraphResponse) GetChildren() []*GraphResponse {
 }
 
 func init() {
-	proto.RegisterType((*UidList)(nil), "pb.UidList")
-	proto.RegisterType((*Result)(nil), "pb.Result")
 	proto.RegisterType((*GraphRequest)(nil), "pb.GraphRequest")
 	proto.RegisterType((*GraphResponse)(nil), "pb.GraphResponse")
 }
@@ -181,22 +143,20 @@ var _DGraph_serviceDesc = grpc.ServiceDesc{
 }
 
 var fileDescriptor0 = []byte{
-	// 265 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x90, 0x4d, 0x4e, 0xc3, 0x30,
-	0x10, 0x85, 0x49, 0x9b, 0x1a, 0x32, 0x2d, 0x12, 0x0c, 0x08, 0x45, 0x08, 0x24, 0xb0, 0x58, 0x94,
-	0x05, 0x59, 0x94, 0x0d, 0x07, 0x40, 0x62, 0x01, 0x1b, 0x2c, 0x71, 0x80, 0x84, 0x58, 0xd4, 0x52,
-	0x68, 0x8c, 0x7f, 0x10, 0x9c, 0x87, 0x8b, 0xe2, 0x8c, 0x0d, 0xa5, 0x62, 0x37, 0x93, 0xf7, 0xe5,
-	0xbd, 0x37, 0x86, 0x83, 0x17, 0x53, 0xeb, 0xa5, 0x91, 0x56, 0xf7, 0x2b, 0x2b, 0x2b, 0x6d, 0x7a,
-	0xd7, 0xe3, 0x48, 0x37, 0xfc, 0x14, 0xb6, 0x9f, 0x54, 0xfb, 0xa0, 0xac, 0x43, 0x84, 0xdc, 0xab,
-	0xd6, 0x96, 0xd9, 0xd9, 0x78, 0x9e, 0x0b, 0x9a, 0xf9, 0x3d, 0x30, 0x21, 0xad, 0xef, 0x1c, 0x1e,
-	0x01, 0x7b, 0xaf, 0x3b, 0x2f, 0xa3, 0x3e, 0x13, 0x69, 0xc3, 0x4b, 0x28, 0x02, 0xf9, 0x5a, 0x3b,
-	0xa3, 0x3e, 0xca, 0x51, 0x90, 0xa6, 0x8b, 0x69, 0xa5, 0x9b, 0x2a, 0xb9, 0x8a, 0xb5, 0xca, 0x2f,
-	0x60, 0x76, 0x37, 0xd4, 0x10, 0xf2, 0x2d, 0xfc, 0xe9, 0xf0, 0x10, 0x26, 0x61, 0x30, 0x9f, 0xc1,
-	0x31, 0x9b, 0x17, 0x22, 0x2e, 0xfc, 0x2b, 0x83, 0xdd, 0x84, 0xc5, 0xb6, 0x78, 0x02, 0x45, 0xed,
-	0x82, 0x43, 0xe3, 0x9d, 0x4c, 0xec, 0xfa, 0x03, 0x72, 0x60, 0x86, 0x2a, 0x86, 0xf4, 0x2c, 0xa4,
-	0xc3, 0x90, 0x1e, 0x4b, 0x8b, 0xa4, 0xe0, 0xf9, 0x4f, 0xd2, 0x98, 0x90, 0x8d, 0x82, 0x51, 0xc1,
-	0x2b, 0xd8, 0x79, 0x5e, 0xaa, 0xae, 0x35, 0x72, 0x55, 0xe6, 0x74, 0xc6, 0xfe, 0x40, 0x6d, 0x34,
-	0x11, 0xbf, 0xc8, 0xe2, 0x06, 0xd8, 0x2d, 0x69, 0x58, 0xc1, 0xe4, 0x91, 0x1c, 0xf6, 0xfe, 0xf0,
-	0x74, 0xe0, 0xf1, 0x7f, 0x07, 0xbe, 0xd5, 0x30, 0x7a, 0xfc, 0xeb, 0xef, 0x00, 0x00, 0x00, 0xff,
-	0xff, 0x18, 0x87, 0x57, 0xd8, 0x93, 0x01, 0x00, 0x00,
+	// 227 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0x2f, 0x4a, 0x2c,
+	0xc8, 0x28, 0x4a, 0x2d, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17,
+	0x62, 0x2a, 0x48, 0x52, 0x52, 0xe1, 0xe2, 0x71, 0x07, 0x49, 0x05, 0xa5, 0x16, 0x96, 0xa6, 0x16,
+	0x97, 0x08, 0x89, 0x70, 0xb1, 0x02, 0x19, 0x45, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41,
+	0x10, 0x8e, 0xd2, 0x39, 0x46, 0x2e, 0x5e, 0xa8, 0x32, 0x88, 0x09, 0x42, 0x32, 0x5c, 0x9c, 0x89,
+	0x25, 0x25, 0x45, 0x99, 0x49, 0xa5, 0x25, 0xa9, 0x50, 0xb5, 0x08, 0x01, 0x21, 0x53, 0x2e, 0xb6,
+	0xb2, 0xc4, 0x1c, 0xa0, 0x81, 0x12, 0x4c, 0x0a, 0xcc, 0x1a, 0xdc, 0x46, 0xb2, 0x7a, 0x05, 0x49,
+	0x7a, 0x28, 0x06, 0xe8, 0x85, 0x81, 0xe5, 0x5d, 0xf3, 0x4a, 0x8a, 0x2a, 0x83, 0xa0, 0x8a, 0x85,
+	0x74, 0xb9, 0x38, 0x92, 0x33, 0x32, 0x73, 0x52, 0x8a, 0x52, 0xf3, 0x24, 0x98, 0xc1, 0x1a, 0x05,
+	0x31, 0x34, 0x06, 0xc1, 0x95, 0x48, 0x59, 0x72, 0x71, 0x23, 0x99, 0x22, 0x24, 0xc0, 0xc5, 0x9c,
+	0x9d, 0x0a, 0x73, 0x38, 0x88, 0x09, 0xf2, 0x0c, 0xd8, 0x64, 0xa0, 0x2b, 0x18, 0x35, 0x78, 0x82,
+	0x20, 0x1c, 0x2b, 0x26, 0x0b, 0x46, 0x23, 0x0b, 0x2e, 0x36, 0x17, 0xb0, 0xb1, 0x42, 0x7a, 0x5c,
+	0xac, 0x81, 0x20, 0x3f, 0x0a, 0x09, 0x20, 0x59, 0x05, 0x0e, 0x0b, 0x29, 0x4c, 0xcb, 0x95, 0x18,
+	0x92, 0xd8, 0xc0, 0x61, 0x67, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x30, 0x75, 0x05, 0xc3, 0x52,
+	0x01, 0x00, 0x00,
 }
diff --git a/query/pb/graphresponse.proto b/query/pb/graphresponse.proto
index c87873acd8da87e319ea4771079b0a82df90a8bf..532e60c2d3fa9e6c590574c9b8a70cf4615e652d 100644
--- a/query/pb/graphresponse.proto
+++ b/query/pb/graphresponse.proto
@@ -8,22 +8,12 @@ service DGraph {
   rpc Query (GraphRequest) returns (GraphResponse) {}
 }
 
-message UidList {
-  repeated uint64 uids = 1;
-}
-
-message Result {
-  repeated bytes values = 1;
-  repeated UidList uidmatrix = 2;
-}
-
 message GraphRequest {
   string query = 1;
 }
 
 message GraphResponse {
   string attribute = 1;
-  Result result = 2;
-  UidList query = 3;
-  repeated GraphResponse children = 4; // Each node can have multiple children
+  map<string, bytes> values = 2;
+  repeated GraphResponse children = 3; // Each node can have multiple children
 }
diff --git a/query/query.go b/query/query.go
index 70771b4bb334ced23ecf04c2c5e48b38735b05c3..ba2713437505944e2ae72bc5e99d1cfd5c8a2aa4 100644
--- a/query/query.go
+++ b/query/query.go
@@ -252,59 +252,72 @@ func (g *SubGraph) ToJson(l *Latency) (js []byte, rerr error) {
 	return json.Marshal(r)
 }
 
+type result struct {
+	values    [][]byte
+	uidmatrix [][]uint64
+}
+
 // This method take in a flatbuffer result, extracts values and uids from it
 // and converts it to a protocol buffer result
-func extract(q *task.Query, r *task.Result) (*pb.UidList, *pb.Result, error) {
-	result := &pb.Result{}
-	query := &pb.UidList{}
+func extract(q *task.Query, r *task.Result) ([]uint64, *result, error) {
+	re := new(result)
+	var qu []uint64
 	var ul task.UidList
 
 	for i := 0; i < q.UidsLength(); i++ {
 		uid := q.Uids(i)
-		query.Uids = append(query.Uids, uid)
+		qu = append(qu, uid)
 	}
 
 	for i := 0; i < r.UidmatrixLength(); i++ {
 		if ok := r.Uidmatrix(&ul, i); !ok {
-			return query, result, fmt.Errorf("While parsing UidList")
+			return qu, re, fmt.Errorf("While parsing UidList")
 		}
 
-		uidList := &pb.UidList{}
+		var uidList []uint64
 		for j := 0; j < ul.UidsLength(); j++ {
 			uid := ul.Uids(j)
-			uidList.Uids = append(uidList.Uids, uid)
+			uidList = append(uidList, uid)
 		}
-		result.Uidmatrix = append(result.Uidmatrix, uidList)
+		re.uidmatrix = append(re.uidmatrix, uidList)
 	}
 
 	var tv task.Value
 	for i := 0; i < r.ValuesLength(); i++ {
 		if ok := r.Values(&tv, i); !ok {
-			return query, result, fmt.Errorf("While parsing value")
+			return qu, re, fmt.Errorf("While parsing value")
 		}
 
 		var ival interface{}
 		if err := posting.ParseValue(&ival, tv.ValBytes()); err != nil {
-			return query, result, err
+			return qu, re, err
 		}
 
 		if ival == nil {
 			ival = ""
 		}
-		result.Values = append(result.Values, []byte(ival.(string)))
+		re.values = append(re.values, []byte(ival.(string)))
 	}
-	return query, result, nil
+	return qu, re, nil
+}
+
+// Struct to store reference to the subgraph associated with a protocol buffer
+// response
+type sgreference struct {
+	uid uint64
+	sg  *SubGraph
 }
 
-// This method performs a pre traversal on a subgraph and converts it to a
-// protocol buffer Graph Response.
-func (g *SubGraph) PreTraverse() (gr *pb.GraphResponse, rerr error) {
+// This method converts a subgraph to a protocol buffer response. It transforms
+// the predicate based subgraph to an entity based protocol buffer subgraph.
+func (g *SubGraph) ToProtocolBuffer() (gr *pb.GraphResponse, rerr error) {
 	gr = &pb.GraphResponse{}
+	gr.Attribute = g.Attr
+
 	if len(g.query) == 0 {
 		return gr, nil
 	}
 
-	gr.Attribute = g.Attr
 	ro := flatbuffers.GetUOffsetT(g.result)
 	r := new(task.Result)
 	r.Init(g.result, ro)
@@ -313,24 +326,89 @@ func (g *SubGraph) PreTraverse() (gr *pb.GraphResponse, rerr error) {
 	q := new(task.Query)
 	q.Init(g.query, uo)
 
-	query, result, err := extract(q, r)
+	_, result, err := extract(q, r)
 	if err != nil {
 		return gr, err
 	}
 
-	gr.Query = query
-	gr.Result = result
+	re := &sgreference{}
+	re.sg = g
+	// Stores the uid for the root node in the reference struct.
+	re.uid = result.uidmatrix[0][0]
 
-	for _, child := range g.Children {
-		childPb, err := child.PreTraverse()
+	gr.Values, gr.Children, rerr = re.pretraverse()
+	if rerr != nil {
+		x.Err(glog, rerr).Error("Error while traversal")
+		return gr, rerr
+	}
+	return gr, nil
+}
+
+// This function performs a binary search on the uids slice and returns the
+// index at which it finds the uid, else returns -1
+func indexOf(uid uint64, uids []uint64) int {
+	low, mid, high := 0, 0, len(uids)-1
+	for low <= high {
+		mid = (low + high) / 2
+		if uids[mid] == uid {
+			return mid
+		} else if uids[mid] > uid {
+			high = mid - 1
+		} else {
+			low = mid + 1
+		}
+	}
+	return -1
+}
+
+// This method gets the values and children for a GraphResponse.
+func (re *sgreference) pretraverse() (map[string][]byte,
+	[]*pb.GraphResponse, error) {
+	vals := make(map[string][]byte)
+	var children []*pb.GraphResponse
+
+	for _, child := range re.sg.Children {
+		ro := flatbuffers.GetUOffsetT(child.result)
+		r := new(task.Result)
+		r.Init(child.result, ro)
+
+		uo := flatbuffers.GetUOffsetT(child.query)
+		q := new(task.Query)
+		q.Init(child.query, uo)
+
+		query, result, err := extract(q, r)
 		if err != nil {
-			x.Err(glog, err).Error("Error while traversal")
-			return gr, err
+			x.Err(glog, err).Error("Error while extracting query, result")
+			return vals, children, fmt.Errorf("While extracting query, result")
 		}
 
-		gr.Children = append(gr.Children, childPb)
+		idx := indexOf(re.uid, query)
+
+		if len(child.Children) == 0 {
+			vals[child.Attr] = result.values[idx]
+		} else {
+			uids := result.uidmatrix[idx]
+			// We create as many predicate children as the number of uids.
+			for _, uid := range uids {
+				predChild := new(pb.GraphResponse)
+				predChild.Attribute = child.Attr
+
+				ref := new(sgreference)
+				ref.sg = child
+				ref.uid = uid
+
+				vals, ch, rerr := ref.pretraverse()
+				if rerr != nil {
+					x.Err(glog, rerr).Error("Error while traversal")
+					return vals, children, rerr
+				}
+
+				predChild.Values, predChild.Children = vals, ch
+				children = append(children, predChild)
+			}
+		}
 	}
-	return gr, nil
+	return vals, children, nil
 }
 
 func treeCopy(gq *gql.GraphQuery, sg *SubGraph) {
diff --git a/query/query_test.go b/query/query_test.go
index 792741f14ebcd68ad4e355ffc5de8fdde18a7fdb..b25b63f5af5b2e3c3f360036b88b297fc1ca826f 100644
--- a/query/query_test.go
+++ b/query/query_test.go
@@ -320,7 +320,7 @@ func TestToJson(t *testing.T) {
 	fmt.Printf(string(js))
 }
 
-func TestPreTraverse(t *testing.T) {
+func TestToProtocolBuffer(t *testing.T) {
 	dir, _ := populateGraph(t)
 	defer os.RemoveAll(dir)
 
@@ -353,44 +353,39 @@ func TestPreTraverse(t *testing.T) {
 		t.Error(err)
 	}
 
-	ugr, err := sg.PreTraverse()
+	gr, err := sg.ToProtocolBuffer()
 	if err != nil {
 		t.Error(err)
 	}
 
-	if len(ugr.Children) != 4 {
-		t.Errorf("Expected len 4. Got: %v", ugr.Children)
+	if gr.Attribute != "_root_" {
+		t.Errorf("Expected attribute _root_, Got: %v", gr.Attribute)
 	}
-	child := ugr.Children[0]
-	if child.Attribute != "name" {
-		t.Errorf("Expected attr name. Got: %v", child.Attribute)
+	if len(gr.Values) != 3 {
+		t.Errorf("Expected values map to contain 3 properties, Got: %v",
+			len(gr.Values))
 	}
-	if string(child.Result.Values[0]) != "Michonne" {
-		t.Errorf("Expected value Michonne. Got %v",
-			string(child.Result.Values[0]))
+	if string(gr.Values["name"]) != "Michonne" {
+		t.Errorf("Expected property name to have value Michonne, Got: %v",
+			string(gr.Values["name"]))
 	}
-	child = ugr.Children[3]
+	if len(gr.Children) != 5 {
+		t.Errorf("Expected 5 children, Got: %v", len(gr.Children))
+	}
+
+	child := gr.Children[0]
 	if child.Attribute != "friend" {
-		t.Errorf("Expected attr friend. Got: %v", child.Attribute)
+		t.Errorf("Expected attribute friend, Got: %v", child.Attribute)
 	}
-	uids := child.Result.Uidmatrix[0].Uids
-	if uids[0] != 23 || uids[1] != 24 || uids[2] != 25 || uids[3] != 31 ||
-		uids[4] != 101 {
-		t.Errorf("Friend ids don't match")
+	if len(child.Values) != 1 {
+		t.Errorf("Expected values map to contain 1 property, Got: %v",
+			len(child.Values))
 	}
-	// To check for name of friends
-	child = child.Children[0]
-	if child.Attribute != "name" {
-		t.Errorf("Expected attr friend. Got: %v", child.Attribute)
+	if string(child.Values["name"]) != "Rick Grimes" {
+		t.Errorf("Expected property name to have value Rick Grimes, Got: %v",
+			string(child.Values["name"]))
 	}
-	if len(child.Query.Uids) != 5 {
-		t.Errorf("Expected 5 uids in query. Got: %v", len(child.Query.Uids))
-	}
-
-	names := child.Result.Values
-
-	if string(names[0]) != "Rick Grimes" || string(names[1]) != "Glenn Rhee" ||
-		string(names[2]) != "Daryl Dixon" || string(names[3]) != "Andrea" {
-		t.Errorf("Names don't match")
+	if len(child.Children) != 0 {
+		t.Errorf("Expected 0 children, Got: %v", len(child.Children))
 	}
 }
diff --git a/server/main.go b/server/main.go
index a5e53c188368d976dc2b2a1c4b56caffebdfacd3..332d41e14d5a0dfa5faeb788e7853becc8ed8673 100644
--- a/server/main.go
+++ b/server/main.go
@@ -241,7 +241,7 @@ func (s *server) Query(ctx context.Context,
 	}
 
 	glog.WithField("q", req.Query).Debug("Graph processed.")
-	resp, err = sg.PreTraverse()
+	resp, err = sg.ToProtocolBuffer()
 	if err != nil {
 		x.Err(glog, err).Error("While converting to protocol buffer.")
 		return resp, err