/// <inheritdoc />
        public virtual void SendRPC(NetDataWriter stream, string rpcName)
        {
            RPCMethodInfo rpcMethodInfo  = null;
            int           rpcMethodIndex = TinyNetStateSyncer.GetRPCMethodInfoFromType(GetType(), rpcName, ref rpcMethodInfo);

            SendRPC(stream, rpcMethodInfo.target, rpcMethodInfo.caller, rpcMethodIndex);
        }
        protected virtual void CreateDirtyFlag()
        {
            int numberOfSyncVars = TinyNetStateSyncer.GetNumberOfSyncedProperties(GetType());

            if (numberOfSyncVars == 0)
            {
                _dirtyFlag = null;
            }
            else if (numberOfSyncVars <= 8)
            {
                _dirtyFlag = new BitArray(8);
            }
            else if (numberOfSyncVars <= 16)
            {
                _dirtyFlag = new BitArray(16);
            }
            else if (numberOfSyncVars <= 32)
            {
                _dirtyFlag = new BitArray(32);
            }
            else if (numberOfSyncVars <= 64)
            {
                _dirtyFlag = new BitArray(64);
            }
            else
            {
                if (TinyNetLogLevel.logError)
                {
                    TinyLogger.LogError("TinyNetBehaviour::OnNetworkCreate amount of TinyNetSyncVar is bigger than 64.");
                }
                return;
            }
        }
        /// <summary>
        /// Registers the RPC delegate.
        /// </summary>
        /// <param name="rpcDel">The RPC delegate.</param>
        /// <param name="methodName">Name of the method.</param>
        protected void RegisterRPCDelegate(RPCDelegate rpcDel, string methodName)
        {
            if (rpcHandlers == null)
            {
                rpcHandlers = new RPCDelegate[TinyNetStateSyncer.GetNumberOfRPCMethods(GetType())];
            }

            int index = TinyNetStateSyncer.GetRPCMethodIndexFromType(GetType(), methodName);

            rpcHandlers[index] = new RPCDelegate(rpcDel);
        }
        /*public bool IsTimeToUpdate() {
         *      if (_bIsDirty && Time.time - _lastSendTime > GetNetworkSendInterval()) {
         *              UpdateDirtyFlag();
         *              return true;
         *      }
         *
         *      return false;
         * }*/

        /// <summary>
        /// <inheritdoc />
        /// Remember that this is called first and before variables are synced.
        /// </summary>
        public virtual void OnNetworkCreate()
        {
            TinyNetStateSyncer.OutPropertyNamesFromType(GetType(), out propertiesName);
            TinyNetStateSyncer.OutPropertyTypesFromType(GetType(), out propertiesTypes);

            CreateAccessors();

            if (isServer)
            {
                UpdateDirtyFlag();
            }
        }
        /// <summary>
        /// Updates the dirty flag.
        /// <para>This will only set dirty values to true, it will not revert them to false.</para>
        /// </summary>
        private void UpdateDirtyFlag()
        {
            TinyNetStateSyncer.UpdateDirtyFlagOf(this, _dirtyFlag);

            IsDirty = false;
            for (int i = 0; i < _dirtyFlag.Length; i++)
            {
                if (_dirtyFlag[i])
                {
                    IsDirty = true;
                }
            }

            _lastSendTime = Time.time;
        }
        /// <inheritdoc />
        public virtual void TinyDeserialize(NetDataReader reader, bool firstStateUpdate)
        {
            if (firstStateUpdate)
            {
                NetworkID = reader.GetInt();
            }

            if (!firstStateUpdate)
            {
                int dFlag = reader.GetInt();

                TinyNetStateSyncer.IntToDirtyFlag(dFlag, _dirtyFlag);
            }

            Type type;
            int  maxSyncVar = propertiesName.Length;

            for (int i = 0; i < maxSyncVar; i++)
            {
                if (!firstStateUpdate && _dirtyFlag[i] == false)
                {
                    continue;
                }

                type = propertiesTypes[i];

                if (type == typeof(byte))
                {
                    byteAccessor[propertiesName[i]].Set(this, reader.GetByte());
                }
                else if (type == typeof(sbyte))
                {
                    sbyteAccessor[propertiesName[i]].Set(this, reader.GetSByte());
                }
                else if (type == typeof(short))
                {
                    shortAccessor[propertiesName[i]].Set(this, reader.GetShort());
                }
                else if (type == typeof(ushort))
                {
                    ushortAccessor[propertiesName[i]].Set(this, reader.GetUShort());
                }
                else if (type == typeof(int))
                {
                    intAccessor[propertiesName[i]].Set(this, reader.GetInt());
                }
                else if (type == typeof(uint))
                {
                    uintAccessor[propertiesName[i]].Set(this, reader.GetUInt());
                }
                else if (type == typeof(long))
                {
                    longAccessor[propertiesName[i]].Set(this, reader.GetLong());
                }
                else if (type == typeof(ulong))
                {
                    ulongAccessor[propertiesName[i]].Set(this, reader.GetULong());
                }
                else if (type == typeof(float))
                {
                    floatAccessor[propertiesName[i]].Set(this, reader.GetFloat());
                }
                else if (type == typeof(double))
                {
                    doubleAccessor[propertiesName[i]].Set(this, reader.GetDouble());
                }
                else if (type == typeof(bool))
                {
                    boolAccessor[propertiesName[i]].Set(this, reader.GetBool());
                }
                else if (type == typeof(string))
                {
                    stringAccessor[propertiesName[i]].Set(this, reader.GetString());
                }
            }
        }
        /// <inheritdoc />
        public virtual void TinySerialize(NetDataWriter writer, bool firstStateUpdate)
        {
            if (firstStateUpdate)
            {
                writer.Put(NetworkID);
            }

            if (!firstStateUpdate)
            {
                writer.Put(TinyNetStateSyncer.DirtyFlagToInt(_dirtyFlag));
            }

            Type type;
            int  maxSyncVar = propertiesName.Length;

            for (int i = 0; i < maxSyncVar; i++)
            {
                if (!firstStateUpdate && _dirtyFlag[i] == false)
                {
                    continue;
                }

                type = propertiesTypes[i];

                if (type == typeof(byte))
                {
                    writer.Put(byteAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(sbyte))
                {
                    writer.Put(sbyteAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(short))
                {
                    writer.Put(shortAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(ushort))
                {
                    writer.Put(ushortAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(int))
                {
                    writer.Put(intAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(uint))
                {
                    writer.Put(uintAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(long))
                {
                    writer.Put(longAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(ulong))
                {
                    writer.Put(ulongAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(float))
                {
                    writer.Put(floatAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(double))
                {
                    writer.Put(doubleAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(bool))
                {
                    writer.Put(boolAccessor[propertiesName[i]].Get(this));
                }
                else if (type == typeof(string))
                {
                    writer.Put(stringAccessor[propertiesName[i]].Get(this));
                }
            }
        }
        /// <summary>
        /// Updates the dirty flag.
        /// </summary>
        private void UpdateDirtyFlag()
        {
            TinyNetStateSyncer.UpdateDirtyFlagOf(this, _dirtyFlag);

            _lastSendTime = Time.time;
        }
		/// <summary>
		/// Does the reflection process.
		/// </summary>
		public static void GetAllSyncVarProps() {
			List<Type> types = GetAllClassesAndChildsOf<TinyNetBehaviour>();

			foreach (Type type in types) {
				PropertyInfo[] props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
					.Where(prop => Attribute.IsDefined(prop, typeof(TinyNetSyncVar)))
					.ToArray();
					//.OrderBy(info => info.Name).ToArray();
				Array.Sort(props, delegate(PropertyInfo x, PropertyInfo y) { return String.Compare(x.Name, y.Name, StringComparison.InvariantCulture); });

				if (props.Length < 32) {

					TinyNetStateSyncer.InitializePropertyInfoListOfType(props.Length, type);

					for (int i = 0; i < props.Length; i++) {
						if (TinyNetSyncVar.allowedTypes.Contains(props[i].PropertyType)) {
							if (TinyNetLogLevel.logDev) { TinyLogger.Log(props[i].Name); }

							//MethodInfo getMethod = props[i].GetGetMethod(true);
							//MethodInfo setMethod = props[i].GetSetMethod(true);

							TinyNetStateSyncer.AddPropertyToType(props[i], type);
						} else {
							if (TinyNetLogLevel.logError) { TinyLogger.LogError("TinyNetSyncVar used in incompatible property type: " + props[i].Name); }
						}
					}
				} else {
					if (TinyNetLogLevel.logError) { TinyLogger.LogError("ERROR: " + type + " have more than 32 syncvar"); }
				}

				// Time for the RPC methods
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
					.Where(method => Attribute.IsDefined(method, typeof(TinyNetRPC)))
					.ToArray();
					//.OrderBy(info => info.Name).ToArray();
				Array.Sort(methods, delegate (MethodInfo x, MethodInfo y) { return String.Compare(x.Name, y.Name, StringComparison.InvariantCulture); });

				TinyNetStateSyncer.InitializeRPCMethodsOfType(methods.Length, type);

				ParameterInfo[] pars;
				bool bValid = true;
				TinyNetRPC rpcAttribute;

				for (int i = 0; i < methods.Length; i++) {
					pars = methods[i].GetParameters();
					rpcAttribute = (TinyNetRPC)methods[i].GetCustomAttributes(typeof(TinyNetRPC), true)[0];

					bValid = true;
					for (int x = 0; x < pars.Length; x++) {
						if (!TinyNetSyncVar.allowedTypes.Contains(pars[x].ParameterType)) {
							if (TinyNetLogLevel.logError) { TinyLogger.LogError("TinyNetRPC used with incompatible parameter: " + pars[x].Name); }
							bValid = false;
						}
					}

					if (bValid) {
						if (TinyNetLogLevel.logDev) { TinyLogger.Log(methods[i].Name); }

						TinyNetStateSyncer.AddRPCMethodNameToType(methods[i].Name, rpcAttribute.Targets, rpcAttribute.Callers, type);
					}
				}
			}
		}