diff --git a/src/person.cpp b/src/person.cpp
index 73a7027753e9764bd3efb6ed5ce66683f703b070..ee205f0ef2c879e856bd1509be58e168f652aca3 100644
--- a/src/person.cpp
+++ b/src/person.cpp
@@ -224,6 +224,40 @@ Person::Person(const QByteArray& content, Person::Encoding encoding, CollectionI
    };
 }
 
+/**
+ * Copy constructor, useful when transferring a contact between collections
+ *
+ * For example, converting a trust request to GMail contact without forcing
+ * a slow vCard conversion.
+ *
+ * This create a COPY of the person details, using shared attributes between
+ * multiple person with multiple collection is currently not supported (but
+ * would be easy to enable if the need arise).
+ */
+Person::Person(const Person& other) noexcept : ItemBase(nullptr),
+d_ptr(new PersonPrivate(this))
+{
+   d_ptr->m_FirstName            = other.d_ptr->m_FirstName           ;
+   d_ptr->m_SecondName           = other.d_ptr->m_SecondName          ;
+   d_ptr->m_NickName             = other.d_ptr->m_NickName            ;
+   d_ptr->m_vPhoto               = other.d_ptr->m_vPhoto              ;
+   d_ptr->m_FormattedName        = other.d_ptr->m_FormattedName       ;
+   d_ptr->m_PreferredEmail       = other.d_ptr->m_PreferredEmail      ;
+   d_ptr->m_Organization         = other.d_ptr->m_Organization        ;
+   d_ptr->m_Uid                  = other.d_ptr->m_Uid                 ;
+   d_ptr->m_Group                = other.d_ptr->m_Group               ;
+   d_ptr->m_Department           = other.d_ptr->m_Department          ;
+   d_ptr->m_DisplayPhoto         = other.d_ptr->m_DisplayPhoto        ;
+   d_ptr->m_Numbers              = other.d_ptr->m_Numbers             ;
+   d_ptr->m_Active               = other.d_ptr->m_Active              ;
+   d_ptr->m_isPlaceHolder        = other.d_ptr->m_isPlaceHolder       ;
+   d_ptr->m_lAddresses           = other.d_ptr->m_lAddresses          ;
+   d_ptr->m_lCustomAttributes    = other.d_ptr->m_lCustomAttributes   ;
+   d_ptr->m_LastUsed             = other.d_ptr->m_LastUsed            ;
+   d_ptr->m_LastUsedInit         = other.d_ptr->m_LastUsedInit        ;
+   d_ptr->m_HiddenContactMethods = other.d_ptr->m_HiddenContactMethods;
+}
+
 ///Updates an existing contact from vCard info
 void Person::updateFromVCard(const QByteArray& content)
 {
diff --git a/src/person.h b/src/person.h
index eeb89c5f184cfd111f4093b29387e69f5621e762..cdc26aec5a25ca7a3bb861b5d8451d41a92c91a5 100644
--- a/src/person.h
+++ b/src/person.h
@@ -122,6 +122,7 @@ public:
    //Constructors & Destructors
    explicit Person(CollectionInterface* parent = nullptr, const QByteArray& uid = QByteArray());
    Person(const QByteArray& content, Person::Encoding encoding = Encoding::UID, CollectionInterface* parent = nullptr);
+   Person(const Person& other) noexcept;
    virtual ~Person();
 
    //Getters
diff --git a/src/private/person_p.h b/src/private/person_p.h
index 69d35303198cd34a0181deb8454f0fd4a1579ffe..ac28b137a54063c3016643d6c7901baa956520e9 100644
--- a/src/private/person_p.h
+++ b/src/private/person_p.h
@@ -27,12 +27,12 @@
 #include "person.h"
 class ContactMethod;
 
-class PersonPrivate : public QObject
+class PersonPrivate final : public QObject
 {
    Q_OBJECT
    friend class ContactMethod;
 public:
-   PersonPrivate(Person* contact);
+   explicit PersonPrivate(Person* contact);
    ~PersonPrivate();
    QString                  m_FirstName           ;
    QString                  m_SecondName          ;
@@ -54,6 +54,14 @@ public:
    bool                     m_LastUsedInit        ;
    QList<ContactMethod*>    m_HiddenContactMethods;
 
+   /*
+    * NOTE If new attributes are added, please update the explicit Person copy
+    * constructor as Qt force QObject copy via serialization (to force developers
+    * to use references, copy-on-write based containers and smart pointers
+    * instead), which is overkill for this scenario and would detach all the
+    * containers causing useless increase in memory usage.
+   */
+
    //Cache
    QString m_CachedFilterString;