@@ -155,6 +155,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
     private String axolotlFingerprint = null;
     private String errorMessage = null;
     private Set<ReadByMarker> readByMarkers = new CopyOnWriteArraySet<>();
+    protected Message mInReplyTo = null;
 
     private Boolean isGeoUri = null;
     private Boolean isEmojisOnly = null;
@@ -440,6 +441,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
         addPayload(fallback);
 
         appendBody(body);
+        setInReplyTo(replyTo);
     }
 
     public Message react(String emoji) {
@@ -905,6 +907,14 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
                         ReadByMarker::getRealJid));
     }
 
+    public void setInReplyTo(final Message m) {
+        mInReplyTo = m;
+    }
+
+    public Message getInReplyTo() {
+        return mInReplyTo;
+    }
+
     boolean similar(Message message) {
         if (!isPrivateMessage() && this.serverMsgId != null && message.getServerMsgId() != null) {
             return this.serverMsgId.equals(message.getServerMsgId()) || Edit.wasPreviouslyEditedServerMsgId(edits, message.getServerMsgId());
  
  
  
    
    @@ -6,6 +6,7 @@ import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.text.TextUtils;
 import android.os.Environment;
 import android.os.SystemClock;
 import android.util.Base64;
@@ -35,7 +36,9 @@ import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -1097,7 +1100,17 @@ public class DatabaseBackend extends SQLiteOpenHelper {
         return getMessages(conversations, limit, -1);
     }
 
-    public Message getMessageFuzzyId(Conversation conversation, String id) {
+    public Map<String, Message> getMessageFuzzyIds(Conversation conversation, Collection<String> ids) {
+        final var result = new Hashtable<String, Message>();
+        if (ids.size() < 1) return result;
+        final ArrayList<String> params = new ArrayList<>();
+        final ArrayList<String> template = new ArrayList<>();
+        for (final var id : ids) {
+            template.add("?");
+        }
+        params.addAll(ids);
+        params.addAll(ids);
+        params.addAll(ids);
         ArrayList<Message> list = new ArrayList<>();
         SQLiteDatabase db = this.getReadableDatabase();
         Cursor cursor;
@@ -1105,18 +1118,22 @@ public class DatabaseBackend extends SQLiteOpenHelper {
             "SELECT * FROM " + Message.TABLENAME + " " +
             "LEFT JOIN cheogram." + Message.TABLENAME +
             "  USING (" + Message.UUID + ")" +
-            "WHERE " + Message.UUID + "=? OR " + Message.SERVER_MSG_ID + " =? OR " + Message.REMOTE_MSG_ID + " =?",
-            new String[]{id,id,id}
+            "WHERE " + Message.UUID + " IN (" + TextUtils.join(",", template) + ") OR " + Message.SERVER_MSG_ID + " IN (" + TextUtils.join(",", template) + ") OR " + Message.REMOTE_MSG_ID + " IN (" + TextUtils.join(",", template) + ")",
+            params.toArray(new String[0])
         );
+
         while (cursor.moveToNext()) {
             try {
-                return Message.fromCursor(cursor, conversation);
+                final var m = Message.fromCursor(cursor, conversation);
+                if (ids.contains(m.getUuid())) result.put(m.getUuid(), m);
+                if (ids.contains(m.getServerMsgId())) result.put(m.getServerMsgId(), m);
+                if (ids.contains(m.getRemoteMsgId())) result.put(m.getRemoteMsgId(), m);
             } catch (Exception e) {
                 Log.e(Config.LOGTAG, "unable to restore message");
             }
         }
         cursor.close();
-        return null;
+        return result;
     }
 
     public ArrayList<Message> getMessages(Conversation conversation, int limit, long timestamp) {
@@ -1155,13 +1172,26 @@ public class DatabaseBackend extends SQLiteOpenHelper {
             );
         }
         CursorUtils.upgradeCursorWindowSize(cursor);
+        final Multimap<String, Message> waitingForReplies = HashMultimap.create();
+        final var replyIds = new HashSet<String>();
         while (cursor.moveToNext()) {
             try {
-                list.add(0, Message.fromCursor(cursor, conversation));
+                final var m = Message.fromCursor(cursor, conversation);
+                final var reply = m.getReply();
+                if (reply != null) {
+                    replyIds.add(reply.getAttribute("id"));
+                    waitingForReplies.put(reply.getAttribute("id"), m);
+                }
+                list.add(0, m);
             } catch (Exception e) {
                 Log.e(Config.LOGTAG, "unable to restore message", e);
             }
         }
+        for (final var parent : getMessageFuzzyIds(conversation, replyIds).entrySet()) {
+            for (final var m : waitingForReplies.get(parent.getKey())) {
+                m.setInReplyTo(parent.getValue());
+            }
+        }
         cursor.close();
         return list;
     }
  
  
  
    
    @@ -671,8 +671,8 @@ public class XmppConnectionService extends Service {
         return this.databaseBackend.getMessage(conversation, uuid);
     }
 
-    public Message getMessageFuzzyId(Conversation conversation, String id) {
-        return this.databaseBackend.getMessageFuzzyId(conversation, id);
+    public Map<String, Message> getMessageFuzzyIds(Conversation conversation, Collection<String> ids) {
+        return this.databaseBackend.getMessageFuzzyIds(conversation, ids);
     }
 
     public void insertWebxdcUpdate(final WebxdcUpdate update) {
  
  
  
    
    @@ -2947,9 +2947,9 @@ public class ConversationFragment extends XmppFragment
             this.binding.textinputSubject.setText(message.getSubject());
             this.binding.textinputSubject.setVisibility(View.VISIBLE);
         }
-        final var reply = message.getReply();
-        if (reply != null) {
-            setupReply(activity.xmppConnectionService.getMessageFuzzyId(conversation, reply.getAttribute("id")));
+        final var replyTo = message.getInReplyTo();
+        if (replyTo != null) {
+            setupReply(replyTo);
         }
     }