public Property(object value, PropertyConflictResolution conflictRes = PropertyConflictResolution.NO_SYNC_ON_CONFLICT)
 {
     Value      = value;
     OnConflict = conflictRes;
 }
        /// <summary>
        /// A synchronization has been requested
        /// </summary>
        protected virtual void _SyncRequest(Client client, Packet packet)
        {
            if (packet.Id != Packet.SYNC_ID || packet.Specifier != PROP_SYNC_SPEC)
            {
                return;
            }

            if (packet.ContentLength % 2 != 0)
            {
                client.LogNotNull(Logging.LogLevel.ERROR, "PRPSYNC packet received with odd length");
                client.Send(new Packet(Packet.PACKET_MALFORMED_HEADER, packet.Id, packet.Specifier)
                {
                    Designation = "PRPSYNC packet malformed (odd property length)"
                });
                return;
            }

            if (packet.Header == Packet.OK_HEADER)
            {
                var response = new List <object>();
                var toSet    = new Dictionary <string, Property>();
                var exclude  = new List <string>();

                for (int i = 0; i < packet.ContentLength; i += 2)
                {
                    string   temp = packet.Get(i) as string;
                    Property prop = packet.Get(i + 1) as Property;
                    if (String.IsNullOrEmpty(temp) || prop == null)
                    {
                        client.LogNotNull(Logging.LogLevel.ERROR, "Malformed PRPSYNC packet received");
                        client.Send(new Packet(Packet.PACKET_MALFORMED_HEADER, packet.Id, packet.Specifier)
                        {
                            Designation = "PRPSYNC packet malformed. Key null or not a string, or property null or of wrong type"
                        });
                        return;
                    }

                    if (Has(temp))
                    {
                        PropertyConflictResolution pcr = Get(temp).OnConflict;
                        if ((pcr == PropertyConflictResolution.CLIENT_OVERWRITE && client.ServerSide) ||
                            (pcr == PropertyConflictResolution.SERVER_OVERWRITE && !client.ServerSide))
                        {
                            toSet.Add(temp, prop);
                        }
                        else if (pcr != PropertyConflictResolution.NO_SYNC && pcr != PropertyConflictResolution.NO_SYNC_ON_CONFLICT)
                        {
                            response.Add(temp);
                            response.Add(Get(temp));
                        }
                        else
                        {
                            exclude.Add(temp);
                        }
                    }
                    else if (prop.OnConflict != PropertyConflictResolution.NO_SYNC)
                    {
                        toSet.Add(temp, prop);
                    }
                }

                foreach (var ts in toSet)
                {
                    Set(ts.Key, ts.Value, true);
                }

                foreach (var entry in Handle)
                {
                    if (response.Contains(entry.Key) || toSet.ContainsKey(entry.Key) || exclude.Contains(entry.Key))
                    {
                        continue;
                    }

                    response.Add(entry.Key);
                    response.Add(entry.Value);
                }
                client.Send(new Packet(Packet.CONFIRMATION_AWAIT_HEADER, packet.Id, packet.Specifier, response.ToArray())
                {
                    Designation = "PRPSYNC conflict resolution"
                });
            }
            else if (packet.Header == Packet.CONFIRMATION_AWAIT_HEADER)
            {
                var toSet = new Dictionary <string, Property>();
                for (int i = 0; i < packet.ContentLength; i += 2)
                {
                    string   temp = packet.Get(i) as string;
                    Property prop = packet.Get(i + 1) as Property;
                    if (String.IsNullOrEmpty(temp) || prop == null)
                    {
                        client.LogNotNull(Logging.LogLevel.ERROR, "Malformed PRPSYNC packet received");
                        client.Send(new Packet(Packet.PACKET_MALFORMED_HEADER, packet.Id, packet.Specifier)
                        {
                            Designation = "PRPSYNC packet malformed. Key null or not a string, or property null or not of type"
                        });
                        return;
                    }

                    //in case it happens...
                    if (!Has(temp) && prop.OnConflict != PropertyConflictResolution.NO_SYNC)
                    {
                        toSet.Add(temp, prop);
                        continue;
                    }

                    PropertyConflictResolution pcr = prop.OnConflict;
                    if ((pcr == PropertyConflictResolution.CLIENT_OVERWRITE && client.ServerSide) ||
                        (pcr == PropertyConflictResolution.SERVER_OVERWRITE && !client.ServerSide))
                    {
                        toSet.Add(temp, prop);
                    }
                    else
                    {
                        client.LogNotNull(Logging.LogLevel.WARNING, "PRPSYNC conflict couldn't be resolved, inconsistent behaviour. Aborting");
                        client.Send(new Packet(Packet.AMBIGUITY_HEADER, packet.Id, packet.Specifier)
                        {
                            Designation = "Ambiguous and suspicious conflict resolution packet received"
                        });
                        return;
                    }
                }

                foreach (var ts in toSet)
                {
                    Set(ts.Key, ts.Value, true);
                }
                client.Send(new Packet(Packet.ACK_HEADER, packet.Id, packet.Specifier)
                {
                    Designation = "ACK ; Synchronization done"
                });
                OnSynchronization(this);
            }
            else if (packet.Header == Packet.ACK_HEADER)
            {
                OnSynchronization(this);
            }
        }