diff --git a/groupChat/receiveRequest_test.go b/groupChat/receiveRequest_test.go
index 30b1dc975b48972132c5b5a13fe6e6c128dac44e..e39bbebbeac999409ddfe8fc20e6f3e30957f1bc 100644
--- a/groupChat/receiveRequest_test.go
+++ b/groupChat/receiveRequest_test.go
@@ -191,7 +191,7 @@ func TestManager_readRequest(t *testing.T) {
 	theirSIDHPrivKey.Generate(prng)
 	theirSIDHPrivKey.GeneratePublicKey(theirSIDHPubKey)
 
-	_, _ = m.e2e.AddPartner(m.receptionId,
+	_, _ = m.e2e.AddPartner(
 		g.Members[0].ID,
 		g.Members[0].DhKey,
 		m.grp.NewInt(2),
diff --git a/groupChat/receive_test.go b/groupChat/receive_test.go
index f353b83a6c35ccc7865115249cfa86c2e086237d..bc35aee1d8280ebfbf261485b58a6a28476d04fc 100644
--- a/groupChat/receive_test.go
+++ b/groupChat/receive_test.go
@@ -8,361 +8,14 @@
 package groupChat
 
 import (
-	"bytes"
-	"gitlab.com/elixxir/client/stoppable"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/group"
-	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/netTime"
 	"math/rand"
-	"reflect"
 	"strings"
 	"testing"
 	"time"
 )
 
-// Tests that Manager.receive returns the correct message on the callback.
-func TestManager_receive(t *testing.T) {
-	// Setup callback
-	msgChan := make(chan MessageReceive)
-	receiveFunc := func(msg MessageReceive) { msgChan <- msg }
-
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManagerWithStore(prng, 10, 0, nil, receiveFunc, t)
-
-	// Create test parameters
-	contents := []byte("Test group message.")
-	timestamp := netTime.Now()
-	sender := m.gs.GetUser()
-
-	expectedMsg := MessageReceive{
-		GroupID:        g.ID,
-		ID:             group.MessageID{0, 1, 2, 3},
-		Payload:        contents,
-		SenderID:       sender.ID,
-		Timestamp:      timestamp.Local(),
-		RoundTimestamp: timestamp,
-	}
-
-	// Create cMix message and get public message
-	cMixMsg, err := m.newCmixMsg(g, contents, timestamp, g.Members[4], prng)
-	if err != nil {
-		t.Errorf("Failed to create new cMix message: %+v", err)
-	}
-
-	intlMsg, _ := newInternalMsg(cMixMsg.ContentsSize() - publicMinLen)
-	intlMsg.SetTimestamp(timestamp)
-	intlMsg.SetSenderID(m.gs.GetUser().ID)
-	intlMsg.SetPayload(contents)
-	expectedMsg.ID = group.NewMessageID(g.ID, intlMsg.Marshal())
-
-	receiveChan := make(chan message.Receive, 1)
-	stop := stoppable.NewSingle("singleStoppable")
-
-	m.gs.SetUser(g.Members[4], t)
-	go m.receive(receiveChan, stop)
-
-	receiveChan <- message.Receive{
-		Payload:        cMixMsg.Marshal(),
-		RoundTimestamp: timestamp,
-	}
-
-	select {
-	case msg := <-msgChan:
-		if !reflect.DeepEqual(expectedMsg, msg) {
-			t.Errorf("Failed to received expected message."+
-				"\nexpected: %+v\nreceived: %+v", expectedMsg, msg)
-		}
-	case <-time.NewTimer(10 * time.Millisecond).C:
-		t.Errorf("Timed out waiting to receive group message.")
-	}
-}
-
-// Tests that the callback is not called when the message cannot be read.
-func TestManager_receive_ReadMessageError(t *testing.T) {
-	// Setup callback
-	msgChan := make(chan MessageReceive)
-	receiveFunc := func(msg MessageReceive) { msgChan <- msg }
-
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, _ := newTestManagerWithStore(prng, 10, 0, nil, receiveFunc, t)
-
-	receiveChan := make(chan message.Receive, 1)
-	stop := stoppable.NewSingle("singleStoppable")
-
-	go m.receive(receiveChan, stop)
-
-	receiveChan <- message.Receive{
-		Payload: make([]byte, format.MinimumPrimeSize*2),
-	}
-
-	select {
-	case <-msgChan:
-		t.Error("Callback called when message should have errored.")
-	case <-time.NewTimer(5 * time.Millisecond).C:
-	}
-}
-
-// Tests that the quit channel exits the function.
-func TestManager_receive_QuitChan(t *testing.T) {
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, _ := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
-
-	receiveChan := make(chan message.Receive, 1)
-	stop := stoppable.NewSingle("singleStoppable")
-	doneChan := make(chan struct{})
-
-	go func() {
-		m.receive(receiveChan, stop)
-		doneChan <- struct{}{}
-	}()
-
-	if err := stop.Close(); err != nil {
-		t.Errorf("Failed to signal close to process: %+v", err)
-	}
-
-	select {
-	case <-doneChan:
-	case <-time.NewTimer(10 * time.Millisecond).C:
-		t.Errorf("Timed out waiting for thread to quit.")
-	}
-}
-
-// Tests that Manager.readMessage returns the message data for the correct
-// group.
-func TestManager_readMessage(t *testing.T) {
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, expectedGrp := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
-
-	// Create test parameters
-	expectedContents := []byte("Test group message.")
-	expectedTimestamp := netTime.Now()
-	sender := m.gs.GetUser()
-
-	// Create cMix message and get public message
-	cMixMsg, err := m.newCmixMsg(expectedGrp, expectedContents,
-		expectedTimestamp, expectedGrp.Members[4], prng)
-	if err != nil {
-		t.Errorf("Failed to create new cMix message: %+v", err)
-	}
-
-	internalMsg, _ := newInternalMsg(cMixMsg.ContentsSize() - publicMinLen)
-	internalMsg.SetTimestamp(expectedTimestamp)
-	internalMsg.SetSenderID(sender.ID)
-	internalMsg.SetPayload(expectedContents)
-	expectedMsgID := group.NewMessageID(expectedGrp.ID, internalMsg.Marshal())
-
-	// Build message.Receive
-	receiveMsg := message.Receive{
-		ID:             e2e.MessageID{},
-		Payload:        cMixMsg.Marshal(),
-		RoundTimestamp: expectedTimestamp,
-	}
-
-	m.gs.SetUser(expectedGrp.Members[4], t)
-	g, messageID, timestamp, senderID, contents, noFpMatch, err :=
-		m.readMessage(receiveMsg)
-	if err != nil {
-		t.Errorf("readMessage() returned an error: %+v", err)
-	}
-
-	if noFpMatch {
-		t.Error("Fingerprint did not match when it should have.")
-	}
-
-	if !reflect.DeepEqual(expectedGrp, g) {
-		t.Errorf("readMessage() returned incorrect group."+
-			"\nexpected: %#v\nreceived: %#v", expectedGrp, g)
-	}
-
-	if expectedMsgID != messageID {
-		t.Errorf("readMessage() returned incorrect message ID."+
-			"\nexpected: %s\nreceived: %s", expectedMsgID, messageID)
-	}
-
-	if !expectedTimestamp.Equal(timestamp) {
-		t.Errorf("readMessage() returned incorrect timestamp."+
-			"\nexpected: %s\nreceived: %s", expectedTimestamp, timestamp)
-	}
-
-	if !sender.ID.Cmp(senderID) {
-		t.Errorf("readMessage() returned incorrect sender ID."+
-			"\nexpected: %s\nreceived: %s", sender.ID, senderID)
-	}
-
-	if !bytes.Equal(expectedContents, contents) {
-		t.Errorf("readMessage() returned incorrect message."+
-			"\nexpected: %s\nreceived: %s", expectedContents, contents)
-	}
-}
-
-// Error path: an error is returned when a group with a matching group
-// fingerprint cannot be found.
-func TestManager_readMessage_FindGroupKpError(t *testing.T) {
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
-
-	// Create test parameters
-	expectedContents := []byte("Test group message.")
-	expectedTimestamp := netTime.Now()
-
-	// Create cMix message and get public message
-	cMixMsg, err := m.newCmixMsg(
-		g, expectedContents, expectedTimestamp, g.Members[4], prng)
-	if err != nil {
-		t.Errorf("Failed to create new cMix message: %+v", err)
-	}
-
-	cMixMsg.SetKeyFP(format.NewFingerprint([]byte("invalid Fingerprint")))
-
-	// Build message.Receive
-	receiveMsg := message.Receive{
-		ID:             e2e.MessageID{},
-		Payload:        cMixMsg.Marshal(),
-		RoundTimestamp: expectedTimestamp,
-	}
-
-	expectedErr := strings.SplitN(findGroupKeyFpErr, "%", 2)[0]
-
-	m.gs.SetUser(g.Members[4], t)
-	_, _, _, _, _, _, err = m.readMessage(receiveMsg)
-	if err == nil || !strings.Contains(err.Error(), expectedErr) {
-		t.Errorf("readMessage() failed to return the expected error."+
-			"\nexpected: %s\nreceived: %+v", expectedErr, err)
-	}
-}
-
-// Tests that a cMix message created by Manager.newCmixMsg can be read by
-// Manager.readMessage.
-func TestManager_decryptMessage(t *testing.T) {
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManager(prng, t)
-
-	// Create test parameters
-	expectedContents := []byte("Test group message.")
-	expectedTimestamp := netTime.Now()
-
-	// Create cMix message and get public message
-	msg, err := m.newCmixMsg(
-		g, expectedContents, expectedTimestamp, g.Members[4], prng)
-	if err != nil {
-		t.Errorf("Failed to create new cMix message: %+v", err)
-	}
-	publicMsg, err := unmarshalPublicMsg(msg.GetContents())
-	if err != nil {
-		t.Errorf("Failed to unmarshal publicMsg: %+v", err)
-	}
-
-	internalMsg, _ := newInternalMsg(publicMsg.GetPayloadSize())
-	internalMsg.SetTimestamp(expectedTimestamp)
-	internalMsg.SetSenderID(m.gs.GetUser().ID)
-	internalMsg.SetPayload(expectedContents)
-	expectedMsgID := group.NewMessageID(g.ID, internalMsg.Marshal())
-
-	// Read message and check if the outputs are correct
-	messageID, timestamp, senderID, contents, err := m.decryptMessage(g, msg,
-		publicMsg, expectedTimestamp)
-	if err != nil {
-		t.Errorf("decryptMessage() returned an error: %+v", err)
-	}
-
-	if expectedMsgID != messageID {
-		t.Errorf("decryptMessage() returned incorrect message ID."+
-			"\nexpected: %s\nreceived: %s", expectedMsgID, messageID)
-	}
-
-	if !expectedTimestamp.Equal(timestamp) {
-		t.Errorf("decryptMessage() returned incorrect timestamp."+
-			"\nexpected: %s\nreceived: %s", expectedTimestamp, timestamp)
-	}
-
-	if !m.gs.GetUser().ID.Cmp(senderID) {
-		t.Errorf("decryptMessage() returned incorrect sender ID."+
-			"\nexpected: %s\nreceived: %s", m.gs.GetUser().ID, senderID)
-	}
-
-	if !bytes.Equal(expectedContents, contents) {
-		t.Errorf("decryptMessage() returned incorrect message."+
-			"\nexpected: %s\nreceived: %s", expectedContents, contents)
-	}
-}
-
-// Error path: an error is returned when the wrong timestamp is passed in and
-// the decryption key cannot be generated because of the wrong epoch.
-func TestManager_decryptMessage_GetCryptKeyError(t *testing.T) {
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManager(prng, t)
-
-	// Create test parameters
-	contents := []byte("Test group message.")
-	timestamp := netTime.Now()
-
-	// Create cMix message and get public message
-	msg, err := m.newCmixMsg(g, contents, timestamp, g.Members[4], prng)
-	if err != nil {
-		t.Errorf("Failed to create new cMix message: %+v", err)
-	}
-	publicMsg, err := unmarshalPublicMsg(msg.GetContents())
-	if err != nil {
-		t.Errorf("Failed to unmarshal publicMsg: %+v", err)
-	}
-
-	// Check if error is correct
-	expectedErr := strings.SplitN(genCryptKeyMacErr, "%", 2)[0]
-	_, _, _, _, err = m.decryptMessage(g, msg, publicMsg, timestamp.Add(time.Hour))
-	if err == nil || !strings.Contains(err.Error(), expectedErr) {
-		t.Errorf("decryptMessage() failed to return the expected error."+
-			"\nexpected: %s\nreceived: %+v", expectedErr, err)
-	}
-}
-
-// Error path: an error is returned when the decrypted payload cannot be
-// unmarshalled.
-func TestManager_decryptMessage_UnmarshalInternalMsgError(t *testing.T) {
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManager(prng, t)
-
-	// Create test parameters
-	contents := []byte("Test group message.")
-	timestamp := netTime.Now()
-
-	// Create cMix message and get public message
-	msg, err := m.newCmixMsg(g, contents, timestamp, g.Members[4], prng)
-	if err != nil {
-		t.Errorf("Failed to create new cMix message: %+v", err)
-	}
-	publicMsg, err := unmarshalPublicMsg(msg.GetContents())
-	if err != nil {
-		t.Errorf("Failed to unmarshal publicMsg: %+v", err)
-	}
-
-	// Modify publicMsg to have invalid payload
-	publicMsg = mapPublicMsg(publicMsg.Marshal()[:33])
-	key, err := group.NewKdfKey(
-		g.Key, group.ComputeEpoch(timestamp), publicMsg.GetSalt())
-	if err != nil {
-		t.Errorf("failed to create new key: %+v", err)
-	}
-	msg.SetMac(
-		group.NewMAC(key, publicMsg.GetPayload(), g.DhKeys[*g.Members[4].ID]))
-
-	// Check if error is correct
-	expectedErr := strings.SplitN(unmarshalInternalMsgErr, "%", 2)[0]
-	_, _, _, _, err = m.decryptMessage(g, msg, publicMsg, timestamp)
-	if err == nil || !strings.Contains(err.Error(), expectedErr) {
-		t.Errorf("decryptMessage() failed to return the expected error."+
-			"\nexpected: %s\nreceived: %+v", expectedErr, err)
-	}
-}
-
 // Unit test of getCryptKey.
 func Test_getCryptKey(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
diff --git a/groupChat/send_test.go b/groupChat/send_test.go
index 298e421770ac5d0f3469280504e7f650b148062a..55a956d63a035623d1ca90ad4ac135aa40c6c973 100644
--- a/groupChat/send_test.go
+++ b/groupChat/send_test.go
@@ -10,7 +10,8 @@ package groupChat
 import (
 	"bytes"
 	"encoding/base64"
-	"gitlab.com/elixxir/client/cmix"
+	"gitlab.com/elixxir/client/cmix/historical"
+	"gitlab.com/elixxir/client/cmix/identity/receptionID"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/elixxir/primitives/format"
@@ -22,256 +23,50 @@ import (
 	"time"
 )
 
-// Unit test of Manager.Send.
 func TestManager_Send(t *testing.T) {
+	receiveChan := make(chan MessageReceive, 100)
+	receiveFunc := func(msg MessageReceive) {
+		receiveChan <- msg
+	}
+
 	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
+	m, g := newTestManagerWithStore(prng, 1, 0, nil, receiveFunc, t)
 	messageBytes := []byte("Group chat message.")
-	sender := m.gs.GetUser().DeepCopy()
+	reception := &receptionProcessor{
+		m: m,
+		g: g,
+	}
 
-	_, _, _, err := m.Send(g.ID, messageBytes)
+	roundId, _, msgId, err := m.Send(g.ID, messageBytes)
 	if err != nil {
 		t.Errorf("Send() returned an error: %+v", err)
 	}
 
 	// get messages sent with or return an error if no messages were sent
-	var messages []cmix.TargetedCmixMessage
-	if len(m.services.(*testNetworkManager).messages) > 0 {
-		messages = m.services.(*testNetworkManager).GetMsgList(0)
+	var messages []format.Message
+	if len(m.services.(*testNetworkManager).receptionMessages) > 0 {
+		messages = m.services.(*testNetworkManager).receptionMessages[0]
 	} else {
 		t.Error("No group cMix messages received.")
 	}
 
-	timeNow := netTime.Now()
-
-	// Loop through each message and make sure the recipient ID matches a member
-	// in the group and that each message can be decrypted and have the expected
-	// values
-	for _, msg := range messages {
-		// Check if recipient ID is in member list
-		var foundMember group.Member
-		for _, mem := range g.Members {
-			if msg.Recipient.Cmp(mem.ID) {
-				foundMember = mem
-			}
-		}
-
-		// Error if the recipient ID is not found in the member list
-		if foundMember == (group.Member{}) {
-			t.Errorf("Failed to find ID %s in memorship list.", msg.Recipient)
-			continue
-		}
-
-		publicMessage, err := unmarshalPublicMsg(msg.GetContents())
-		if err != nil {
-			t.Errorf("Failed to unmarshal publicMsg: %+v", err)
-		}
-		// Attempt to read the message
-		result, err := decryptMessage(
-			g, msg.Message, publicMessage, timeNow)
-		if err != nil {
-			t.Errorf("Failed to read message for %s: %+v", msg.Recipient, err)
-		}
-
-		internalMessage, _ := newInternalMsg(publicMessage.GetPayloadSize())
-		internalMessage.SetTimestamp(timestamp)
-		internalMessage.SetSenderID(m.gs.GetUser().ID)
-		internalMessage.SetPayload(messageBytes)
-		expectedMsgID := group.NewMessageID(g.ID, internalMessage.Marshal())
-
-		if expectedMsgID != messageID {
-			t.Errorf("Message ID received for %s too different from expected."+
-				"\nexpected: %s\nreceived: %s", msg.Recipient, expectedMsgID, messageID)
-		}
-
-		if !timestamp.Round(5 * time.Second).Equal(timeNow.Round(5 * time.Second)) {
-			t.Errorf("Timestamp received for %s too different from expected."+
-				"\nexpected: %s\nreceived: %s", msg.Recipient, timeNow, timestamp)
-		}
-
-		if !senderID.Cmp(sender.ID) {
-			t.Errorf("Sender ID received for %s incorrect."+
-				"\nexpected: %s\nreceived: %s", msg.Recipient, sender.ID, senderID)
-		}
-
-		if !bytes.Equal(readMsg, messageBytes) {
-			t.Errorf("Message received for %s incorrect."+
-				"\nexpected: %q\nreceived: %q", msg.Recipient, messageBytes, readMsg)
-		}
-	}
-}
-
-// Error path: error is returned when the message is too large.
-func TestManager_Send_CmixMessageError(t *testing.T) {
-	// Set up new test manager that will make SendManyCMIX error
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
-	expectedErr := strings.SplitN(newCmixMsgErr, "%", 2)[0]
-
-	// Send message
-	_, _, _, err := m.Send(g.ID, make([]byte, 400))
-	if err == nil || !strings.Contains(err.Error(), expectedErr) {
-		t.Errorf("Send() failed to return the expected error."+
-			"\nexpected: %s\nreceived: %+v", expectedErr, err)
-	}
-}
-
-// Error path: SendManyCMIX returns an error.
-func TestManager_Send_SendManyCMIXError(t *testing.T) {
-	// Set up new test manager that will make SendManyCMIX error
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManagerWithStore(prng, 10, 1, nil, nil, t)
-	expectedErr := strings.SplitN(sendManyCmixErr, "%", 2)[0]
-
-	// Send message
-	_, _, _, err := m.Send(g.ID, []byte("message"))
-	if err == nil || !strings.Contains(err.Error(), expectedErr) {
-		t.Errorf("Send() failed to return the expected error."+
-			"\nexpected: %s\nreceived: %+v", expectedErr, err)
-	}
-
-	// If messages were added, then error
-	if len(m.services.(*testNetworkManager).messages) > 0 {
-		t.Error("Group cMix messages received when SendManyCMIX errors.")
-	}
-}
-
-// Tests that Manager.createMessages generates the messages for the correct
-// group.
-func TestManager_createMessages(t *testing.T) {
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
-
-	testMsg := []byte("Test group message.")
-	sender := m.gs.GetUser()
-	messages, _, err := m.createMessages(g.ID, testMsg, netTime.Now())
-	if err != nil {
-		t.Errorf("createMessages() returned an error: %+v", err)
-	}
-
-	recipients := append(g.Members[:2], g.Members[3:]...)
-
-	i := 0
-	for _, msg := range messages {
-		for _, recipient := range recipients {
-			if !msg.Recipient.Cmp(recipient.ID) {
-				continue
-			}
-
-			publicMessage, err := unmarshalPublicMsg(msg.Message.GetContents())
-			if err != nil {
-				t.Errorf("Failed to unmarshal publicMsg: %+v", err)
-			}
-
-			messageID, timestamp, testSender, testMessage, err := m.decryptMessage(
-				g, msg.Message, publicMessage, netTime.Now())
-			if err != nil {
-				t.Errorf("Failed to find member to read message %d: %+v", i, err)
-			}
-
-			internalMessage, _ := newInternalMsg(publicMessage.GetPayloadSize())
-			internalMessage.SetTimestamp(timestamp)
-			internalMessage.SetSenderID(m.gs.GetUser().ID)
-			internalMessage.SetPayload(testMsg)
-			expectedMsgID := group.NewMessageID(g.ID, internalMessage.Marshal())
-
-			if messageID != expectedMsgID {
-				t.Errorf("Failed to read correct message ID for message %d."+
-					"\nexpected: %s\nreceived: %s", i, expectedMsgID, messageID)
-			}
-
-			if !sender.ID.Cmp(testSender) {
-				t.Errorf("Failed to read correct sender ID for message %d."+
-					"\nexpected: %s\nreceived: %s", i, sender.ID, testSender)
-			}
-
-			if !bytes.Equal(testMsg, testMessage) {
-				t.Errorf("Failed to read correct message for message %d."+
-					"\nexpected: %s\nreceived: %s", i, testMsg, testMessage)
-			}
-		}
-		i++
-	}
-}
-
-// Error path: test that an error is returned when the group ID does not match a
-// group in storage.
-func TestManager_createMessages_InvalidGroupIdError(t *testing.T) {
-	expectedErr := strings.SplitN(newNoGroupErr, "%", 2)[0]
-
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, _ := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
-
-	// Read message and make sure the error is expected
-	_, _, err := m.createMessages(
-		id.NewIdFromString("invalidID", id.Group, t), nil, time.Time{})
-	if err == nil || !strings.Contains(err.Error(), expectedErr) {
-		t.Errorf("createMessages() did not return the expected error."+
-			"\nexpected: %s\nreceived: %+v", expectedErr, err)
-	}
-}
-
-// Tests that Manager.newMessage returns messages with correct data.
-func TestGroup_newMessages(t *testing.T) {
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManager(prng, t)
-
-	testMsg := []byte("Test group message.")
-	sender := m.gs.GetUser()
-	timestamp := netTime.Now()
-	messages, err := m.newMessages(g, testMsg, timestamp)
-	if err != nil {
-		t.Errorf("newMessages() returned an error: %+v", err)
-	}
-
-	recipients := append(g.Members[:2], g.Members[3:]...)
-
-	i := 0
 	for _, msg := range messages {
-		for _, recipient := range recipients {
-			if !msg.Recipient.Cmp(recipient.ID) {
-				continue
+		reception.Process(msg, receptionID.EphemeralIdentity{}, historical.Round{ID: roundId})
+		select {
+		case result := <-receiveChan:
+			if !result.SenderID.Cmp(m.receptionId) {
+				t.Errorf("Sender mismatch")
 			}
-
-			publicMessage, err := unmarshalPublicMsg(msg.Message.GetContents())
-			if err != nil {
-				t.Errorf("Failed to unmarshal publicMsg: %+v", err)
+			if result.ID.String() != msgId.String() {
+				t.Errorf("MsgId mismatch")
 			}
-
-			result, err := decryptMessage(
-				g, msg.Message, publicMessage, netTime.Now())
-			if err != nil {
-				t.Errorf("Failed to find member to read message %d.", i)
+			if !bytes.Equal(result.Payload, messageBytes) {
+				t.Errorf("Payload mismatch")
 			}
-
-			internalMessage, _ := newInternalMsg(publicMessage.GetPayloadSize())
-			internalMessage.SetTimestamp(timestamp)
-			internalMessage.SetSenderID(m.gs.GetUser().ID)
-			internalMessage.SetPayload(testMsg)
-			expectedMsgID := group.NewMessageID(g.ID, internalMessage.Marshal())
-
-			if messageID != expectedMsgID {
-				t.Errorf("Failed to read correct message ID for message %d."+
-					"\nexpected: %s\nreceived: %s", i, expectedMsgID, messageID)
-			}
-
-			if !timestamp.Equal(testTimestamp) {
-				t.Errorf("Failed to read correct timeout for message %d."+
-					"\nexpected: %s\nreceived: %s", i, timestamp, testTimestamp)
-			}
-
-			if !sender.ID.Cmp(testSender) {
-				t.Errorf("Failed to read correct sender ID for message %d."+
-					"\nexpected: %s\nreceived: %s", i, sender.ID, testSender)
-			}
-
-			if !bytes.Equal(testMsg, testMessage) {
-				t.Errorf("Failed to read correct message for message %d."+
-					"\nexpected: %s\nreceived: %s", i, testMsg, testMessage)
+			if result.RoundID != roundId {
+				t.Errorf("Round mismatch")
 			}
 		}
-		i++
 	}
 }
 
@@ -288,88 +83,6 @@ func TestGroup_newMessages_NewCmixMsgError(t *testing.T) {
 	}
 }
 
-// Tests that the message returned by newCmixMsg has all the expected parts.
-func TestGroup_newCmixMsg(t *testing.T) {
-	// Create new test Manager and Group
-	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManager(prng, t)
-
-	// Create test parameters
-	testMsg := []byte("Test group message.")
-	mem := g.Members[3]
-	timeNow := netTime.Now()
-
-	// Create cMix message
-	prng = rand.New(rand.NewSource(42))
-	msg, err := newCmixMsg(g, testMsg, timeNow, mem, prng, m.receptionId, m.grp)
-	if err != nil {
-		t.Errorf("newCmixMsg() returned an error: %+v", err)
-	}
-
-	// Create expected salt
-	prng = rand.New(rand.NewSource(42))
-	var salt [group.SaltLen]byte
-	prng.Read(salt[:])
-
-	// Create expected key
-	key, _ := group.NewKdfKey(g.Key, group.ComputeEpoch(timeNow), salt)
-
-	// Create expected messages
-	cmixMsg := format.NewMessage(m.grp.GetP().ByteLen())
-	publicMessage, _ := newPublicMsg(cmixMsg.ContentsSize())
-	internalMessage, _ := newInternalMsg(publicMessage.GetPayloadSize())
-	internalMessage.SetTimestamp(timeNow)
-	internalMessage.SetSenderID(m.gs.GetUser().ID)
-	internalMessage.SetPayload(testMsg)
-	payload := internalMessage.Marshal()
-
-	// Check if key fingerprint is correct
-	expectedFp := group.NewKeyFingerprint(g.Key, salt, mem.ID)
-	if expectedFp != msg.GetKeyFP() {
-		t.Errorf("newCmixMsg() returned message with wrong key fingerprint."+
-			"\nexpected: %s\nreceived: %s", expectedFp, msg.GetKeyFP())
-	}
-
-	// Check if key MAC is correct
-	encryptedPayload := group.Encrypt(key, expectedFp, payload)
-	expectedMAC := group.NewMAC(key, encryptedPayload, g.DhKeys[*mem.ID])
-	if !bytes.Equal(expectedMAC, msg.GetMac()) {
-		t.Errorf("newCmixMsg() returned message with wrong MAC."+
-			"\nexpected: %+v\nreceived: %+v", expectedMAC, msg.GetMac())
-	}
-
-	// Attempt to unmarshal public group message
-	publicMessage, err = unmarshalPublicMsg(msg.GetContents())
-	if err != nil {
-		t.Errorf("Failed to unmarshal cMix message contents: %+v", err)
-	}
-
-	// Attempt to decrypt payload
-	decryptedPayload := group.Decrypt(key, expectedFp, publicMessage.GetPayload())
-	internalMessage, err = unmarshalInternalMsg(decryptedPayload)
-	if err != nil {
-		t.Errorf("Failed to unmarshal decrypted payload contents: %+v", err)
-	}
-
-	// Check for expected values in internal message
-	if !internalMessage.GetTimestamp().Equal(timeNow) {
-		t.Errorf("Internal message has wrong timestamp."+
-			"\nexpected: %s\nreceived: %s", timeNow, internalMessage.GetTimestamp())
-	}
-	sid, err := internalMessage.GetSenderID()
-	if err != nil {
-		t.Fatalf("Failed to get sender ID from internal message: %+v", err)
-	}
-	if !sid.Cmp(m.gs.GetUser().ID) {
-		t.Errorf("Internal message has wrong sender ID."+
-			"\nexpected: %s\nreceived: %s", m.gs.GetUser().ID, sid)
-	}
-	if !bytes.Equal(internalMessage.GetPayload(), testMsg) {
-		t.Errorf("Internal message has wrong payload."+
-			"\nexpected: %s\nreceived: %s", testMsg, internalMessage.GetPayload())
-	}
-}
-
 // Error path: reader returns an error.
 func TestGroup_newCmixMsg_SaltReaderError(t *testing.T) {
 	expectedErr := strings.SplitN(saltReadErr, "%", 2)[0]
diff --git a/groupChat/utils_test.go b/groupChat/utils_test.go
index d3d1c1599573f34315aec4b256de615d356f1415..88dc69e1b2e79081c0d4817ef675f41bb39628fb 100644
--- a/groupChat/utils_test.go
+++ b/groupChat/utils_test.go
@@ -223,8 +223,9 @@ func getGroup() *cyclic.Group {
 
 func newTestNetworkManager(sendErr int, t *testing.T) cmix.Client {
 	return &testNetworkManager{
-		messages: [][]cmix.TargetedCmixMessage{},
-		sendErr:  sendErr,
+		receptionMessages: [][]format.Message{},
+		sendMessages:      [][]cmix.TargetedCmixMessage{},
+		sendErr:           sendErr,
 	}
 }
 
@@ -271,9 +272,10 @@ func (tnm *testE2eManager) GetReceptionID() *id.ID {
 
 // testNetworkManager is a test implementation of NetworkManager interface.
 type testNetworkManager struct {
-	messages [][]cmix.TargetedCmixMessage
-	errSkip  int
-	sendErr  int
+	receptionMessages [][]format.Message
+	sendMessages      [][]cmix.TargetedCmixMessage
+	errSkip           int
+	sendErr           int
 	sync.RWMutex
 }
 
@@ -289,8 +291,17 @@ func (tnm *testNetworkManager) SendMany(messages []cmix.TargetedCmixMessage, p c
 	tnm.Lock()
 	defer tnm.Unlock()
 
-	tnm.messages = append(tnm.messages, messages)
+	tnm.sendMessages = append(tnm.sendMessages, messages)
 
+	receiveMessages := []format.Message{}
+	for _, msg := range messages {
+		receiveMsg := format.Message{}
+		receiveMsg.SetMac(msg.Mac)
+		receiveMsg.SetContents(msg.Payload)
+		receiveMsg.SetKeyFP(msg.Fingerprint)
+		receiveMessages = append(receiveMessages, receiveMsg)
+	}
+	tnm.receptionMessages = append(tnm.receptionMessages, receiveMessages)
 	return 0, nil, nil
 }
 
@@ -359,7 +370,6 @@ func (*testNetworkManager) IsHealthy() bool {
 }
 
 func (*testNetworkManager) WasHealthy() bool {
-	//TODO implement me
 	panic("implement me")
 }
 
@@ -490,12 +500,6 @@ func (*testE2eManager) GetDefaultID() *id.ID {
 	panic("implement me")
 }
 
-func (tnm *testNetworkManager) GetMsgList(i int) []cmix.TargetedCmixMessage {
-	tnm.RLock()
-	defer tnm.RUnlock()
-	return tnm.messages[i]
-}
-
 func (tnm *testE2eManager) GetE2eMsg(i int) testE2eMessage {
 	tnm.RLock()
 	defer tnm.RUnlock()