void controller_ObjectCreated(object source, ObjectCreatedArgs e)
        {
            if (this.rpc.IsServer)
            {
                LogFile.WriteLine("netreplicationcontroller,server ObjectCreated " + e.TargetObject.GetType());
                //LogFile.WriteLine("controller_ObjectCreated() " + e.TargetObject);
                //NetworkInterfaces.ObjectReplicationServerToClient_ClientProxy objectreplicationproxy = new OSMP.NetworkInterfaces.ObjectReplicationServerToClient_ClientProxy( rpc,
                // handled by something like DirtyCacheController
                dirtyobjectcontroller.MarkDirty(e.TargetObject, new Type[] { typeof(Replicate) });
            }
            else
            {
                LogFile.WriteLine("netreplicationcontroller,client ObjectCreated " + e.TargetObject.GetType());
                int tempreference = GenerateTempReference();
                tempreferences.Add(tempreference, e.TargetObject);

                Type[] AttributeTypeList = new Type[] { typeof(Replicate) };
                int    bitmap            = new ReplicateAttributeHelper().TypeArrayToBitmap(AttributeTypeList);

                byte[] entitydata   = new byte[4096];
                int    nextposition = 0;
                new BinaryPacker().PackObjectUsingSpecifiedAttributes(entitydata, ref nextposition,
                                                                      e.TargetObject, AttributeTypeList);

                byte[] entitydatatotransmit = new byte[nextposition];
                Buffer.BlockCopy(entitydata, 0, entitydatatotransmit, 0, nextposition);

                //LogFile.WriteLine(Encoding.UTF8.GetString(entitydatatotransmit));

                NetworkInterfaces.ObjectReplicationClientToServer_ClientProxy objectreplicationproxy = new OSMP.NetworkInterfaces.ObjectReplicationClientToServer_ClientProxy(rpc, null);
                objectreplicationproxy.ObjectCreated(tempreference, e.TargetObject.GetType().ToString(), bitmap, entitydatatotransmit);
            }
        }
        // incoming rpc calls
        // ===================

        public void ObjectCreatedRpcClientToServer(IPEndPoint connection, int remoteclientreference, string typename, int attributebitmap, byte[] entitydata)
        {
            LogFile.WriteLine("ObjectCreatedRpcClientToServer " + typename);

            //LogFile.WriteLine(Encoding.UTF8.GetString(entitydata));

            // note to self: should probably make a whitelist of allowed typenames, maybe via primitive class registration
            Type          newtype   = Type.GetType(typename);
            IHasReference newobject = (IHasReference)Activator.CreateInstance(newtype);

            IReplicatedObjectController replicatedobjectcontroller = GetControllerForObject(newobject);

            List <Type> AttributeTypeList = new ReplicateAttributeHelper().BitmapToAttributeTypeArray(attributebitmap);

            int nextposition = 0;

            new BinaryPacker().UnpackIntoObjectUsingSpecifiedAttributes(entitydata, ref nextposition,
                                                                        newobject, new Type[] { typeof(Replicate) });
            LogFile.WriteLine("server received replicated object: " + newobject.GetType());

            int newobjectreference = 0;

            if (replicatedobjectcontroller != null && replicatedobjectcontroller is IReferenceGenerator)
            {
                newobjectreference = (replicatedobjectcontroller as IReferenceGenerator).GenerateReference();
            }
            else
            {
                newobjectreference = nextreference;
                nextreference++;
            }

            LogFile.WriteLine("New object reference: " + newobjectreference);
            if (newobject is IHasReference)
            {
                (newobject as IHasReference).Reference = newobjectreference;
            }

            if (replicatedobjectcontroller != null)
            {
                replicatedobjectcontroller.ReplicatedObjectCreated(this,
                                                                   new ObjectCreatedArgs(DateTime.Now, (IHasReference)newobject)); // note to self: untested cast
            }


            new OSMP.NetworkInterfaces.ObjectReplicationServerToClient_ClientProxy(rpc, connection
                                                                                   ).ObjectCreatedServerToCreatorClient(
                remoteclientreference, newobjectreference);

            dirtyobjectcontroller.MarkDirty(newobject, new Type[] { typeof(Replicate) });
        }
        // on server, called from dirtyobjectqueuesingleclient
        public void ReplicateSingleEntityToSingleClient(IPEndPoint connection, IHasReference entity, Type[] dirtyattributes)
        {
            LogFile.WriteLine("ReplicateSingleEntityToSingleClient " + entity.GetType() + " to " + connection);
            int bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(dirtyattributes);

            byte[] entitydata   = new byte[4096];
            int    nextposition = 0;

            new BinaryPacker().PackObjectUsingSpecifiedAttributes(entitydata, ref nextposition,
                                                                  entity, dirtyattributes);

            byte[] entitydatatotransmit = new byte[nextposition];
            Buffer.BlockCopy(entitydata, 0, entitydatatotransmit, 0, nextposition);

            //LogFile.WriteLine(Encoding.UTF8.GetString(entitydatatotransmit));

            new NetworkInterfaces.ObjectReplicationServerToClient_ClientProxy(
                rpc, connection).ObjectModified(
                entity.Reference, entity.GetType().ToString(), bitmap, entitydatatotransmit);
        }
        public void Go()
        {
            int bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(new Type[] { typeof(Replicate) });

            foreach (Type attributetype in new ReplicateAttributeHelper().BitmapToAttributeTypeArray(bitmap))
            {
                LogFile.WriteLine(attributetype);
            }
            LogFile.BlankLine();

            bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(new Type[] { typeof(Movement) });
            foreach (Type attributetype in new ReplicateAttributeHelper().BitmapToAttributeTypeArray(bitmap))
            {
                LogFile.WriteLine(attributetype);
            }
            LogFile.BlankLine();

            bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(new Type[] { typeof(Replicate), typeof(Movement) });
            foreach (Type attributetype in new ReplicateAttributeHelper().BitmapToAttributeTypeArray(bitmap))
            {
                LogFile.WriteLine(attributetype);
            }
            LogFile.BlankLine();
        }
        public void ObjectCreatedRpcServerToClient(IPEndPoint connection, int reference, string typename, int attributebitmap, byte[] entitydata)
        {
            LogFile.WriteLine("ObjectCreatedRpcServerToClient " + typename);

            Type          newtype   = Type.GetType(typename);
            IHasReference newobject = (IHasReference)Activator.CreateInstance(newtype); // note to self: insecure

            IReplicatedObjectController replicatedobjectcontroller = null;

            foreach (Type replicatedtype in objectcontrollers.Keys)
            {
                if (replicatedtype.IsInstanceOfType(newobject))
                {
                    replicatedobjectcontroller = objectcontrollers[replicatedtype];
                }
            }
            if (replicatedobjectcontroller == null)
            {
                LogFile.WriteLine("Error: no controller for received type " + typename);
                return;
            }

            List <Type> AttributeTypeList = new ReplicateAttributeHelper().BitmapToAttributeTypeArray(attributebitmap);

            int nextposition = 0;

            new BinaryPacker().UnpackIntoObjectUsingSpecifiedAttributes(entitydata, ref nextposition,
                                                                        newobject, new Type[] { typeof(Replicate) });

            if (!replicatedobjectcontroller.HasEntityForReference(newobject.Reference))
            {
                LogFile.WriteLine("client received replicated object: " + newobject);
                replicatedobjectcontroller.ReplicatedObjectCreated(this,
                                                                   new ObjectCreatedArgs(DateTime.Now, newobject)); // note to self: untested cast
            }
        }
        public void ObjectModifiedRpc(IPEndPoint connection, int reference, string typename, int attributebitmap, byte[] entity)
        {
            if (rpc.isserver)
            {
                Type modifiedobjecttype = Type.GetType(typename);

                IReplicatedObjectController replicatedobjectcontroller = GetControllerForType(modifiedobjecttype);
                if (replicatedobjectcontroller == null)
                {
                    LogFile.WriteLine("ObjectModifiedRpc. Error: no controller for received type " + typename);
                    return;
                }

                List <Type> AttributeTypeList = new ReplicateAttributeHelper().BitmapToAttributeTypeArray(attributebitmap);

                IHasReference thisobject = replicatedobjectcontroller.GetEntity(reference);
                if (thisobject == null)
                {
                    LogFile.WriteLine("ObjectModifiedRpc received for unknown object " + reference);
                    return;
                }
                int nextposition = 0;
                new BinaryPacker().UnpackIntoObjectUsingSpecifiedAttributes(entity, ref nextposition,
                                                                            thisobject, new Type[] { typeof(Replicate) });

                LogFile.WriteLine("server received replicated modified object: " + thisobject);
                replicatedobjectcontroller.ReplicatedObjectModified(this,
                                                                    new ObjectModifiedArgs(DateTime.Now, thisobject, AttributeTypeList.ToArray()));
                dirtyobjectcontroller.MarkDirty(thisobject, AttributeTypeList.ToArray());
            }
            else
            {
                LogFile.WriteLine("ObjectModifiedRpcServerToClient " + typename);

                Type modifiedobjecttype = Type.GetType(typename);

                IReplicatedObjectController replicatedobjectcontroller = GetControllerForType(modifiedobjecttype);
                if (replicatedobjectcontroller == null)
                {
                    LogFile.WriteLine("ObjectModifiedRpc. Error: no controller for received type " + typename);
                    return;
                }

                List <Type> AttributeTypeList = new ReplicateAttributeHelper().BitmapToAttributeTypeArray(attributebitmap);

                IHasReference thisobject  = replicatedobjectcontroller.GetEntity(reference);
                bool          objectisnew = false;
                if (thisobject == null)
                {
                    LogFile.WriteLine("Creating new object");
                    thisobject  = Activator.CreateInstance(modifiedobjecttype) as IHasReference;
                    objectisnew = true;
                }
                int nextposition = 0;
                new BinaryPacker().UnpackIntoObjectUsingSpecifiedAttributes(entity, ref nextposition,
                                                                            thisobject, new Type[] { typeof(Replicate) });

                LogFile.WriteLine("client received replicated modified object: " + thisobject);
                if (objectisnew)
                {
                    replicatedobjectcontroller.ReplicatedObjectCreated(this,
                                                                       new ObjectCreatedArgs(DateTime.Now, thisobject));
                }
                else
                {
                    replicatedobjectcontroller.ReplicatedObjectModified(this,
                                                                        new ObjectModifiedArgs(DateTime.Now, thisobject, AttributeTypeList.ToArray()));
                }
            }
        }
        public void Go()
        {
            int bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(new Type[] { typeof(Replicate) });
            foreach (Type attributetype in new ReplicateAttributeHelper().BitmapToAttributeTypeArray(bitmap))
            {
                LogFile.WriteLine( attributetype );
            }
            LogFile.BlankLine();

            bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(new Type[] { typeof(Movement) });
            foreach (Type attributetype in new ReplicateAttributeHelper().BitmapToAttributeTypeArray(bitmap))
            {
                LogFile.WriteLine( attributetype );
            }
            LogFile.BlankLine();

            bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(new Type[] { typeof(Replicate), typeof(Movement) });
            foreach (Type attributetype in new ReplicateAttributeHelper().BitmapToAttributeTypeArray(bitmap))
            {
                LogFile.WriteLine( attributetype );
            }
            LogFile.BlankLine();
        }
        // events for incoming changes from object controllers
        void controller_ObjectModified(object source, ObjectModifiedArgs e)
        {
            LogFile.WriteLine("netreplicationcontroller controller_ObjectModified " + e.TargetObject.GetType());
            if (this.rpc.IsServer)
            {
                //LogFile.WriteLine("controller_ObjectCreated() " + e.TargetObject);
                //NetworkInterfaces.ObjectReplicationServerToClient_ClientProxy objectreplicationproxy = new OSMP.NetworkInterfaces.ObjectReplicationServerToClient_ClientProxy( rpc,
                // handled by something like DirtyCacheController
                dirtyobjectcontroller.MarkDirty(e.TargetObject, e.modificationtypeattributes );
            }
            else
            {
                int bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(e.modificationtypeattributes);

                byte[] entitydata = new byte[4096];
                int nextposition = 0;
                new BinaryPacker().PackObjectUsingSpecifiedAttributes(entitydata, ref nextposition,
                    e.TargetObject, e.modificationtypeattributes);

                byte[] entitydatatotransmit = new byte[nextposition];
                Buffer.BlockCopy(entitydata, 0, entitydatatotransmit, 0, nextposition);

                //LogFile.WriteLine(Encoding.UTF8.GetString(entitydatatotransmit));

                NetworkInterfaces.ObjectReplicationClientToServer_ClientProxy objectreplicationproxy = new OSMP.NetworkInterfaces.ObjectReplicationClientToServer_ClientProxy(rpc, null);
                objectreplicationproxy.ObjectModified(e.TargetObject.Reference, e.TargetObject.GetType().ToString(), bitmap, entitydatatotransmit);
            }
        }
        // on server, called from dirtyobjectqueuesingleclient
        public void ReplicateSingleEntityToSingleClient(IPEndPoint connection, IHasReference entity, Type[] dirtyattributes)
        {
            LogFile.WriteLine("ReplicateSingleEntityToSingleClient " + entity.GetType() + " to " + connection);
            int bitmap = new ReplicateAttributeHelper().TypeArrayToBitmap(dirtyattributes);

            byte[] entitydata = new byte[4096];
            int nextposition = 0;
            new BinaryPacker().PackObjectUsingSpecifiedAttributes(entitydata, ref nextposition,
                entity, dirtyattributes);

            byte[] entitydatatotransmit = new byte[nextposition];
            Buffer.BlockCopy(entitydata, 0, entitydatatotransmit, 0, nextposition);

            //LogFile.WriteLine(Encoding.UTF8.GetString(entitydatatotransmit));

            new NetworkInterfaces.ObjectReplicationServerToClient_ClientProxy(
                rpc, connection).ObjectModified(
                entity.Reference, entity.GetType().ToString(), bitmap, entitydatatotransmit);
        }
        public void ObjectModifiedRpc(IPEndPoint connection, int reference, string typename, int attributebitmap, byte[] entity)
        {
            if (rpc.isserver)
            {
                Type modifiedobjecttype = Type.GetType(typename);

                IReplicatedObjectController replicatedobjectcontroller = GetControllerForType(modifiedobjecttype);
                if (replicatedobjectcontroller == null)
                {
                    LogFile.WriteLine("ObjectModifiedRpc. Error: no controller for received type " + typename);
                    return;
                }

                List<Type> AttributeTypeList = new ReplicateAttributeHelper().BitmapToAttributeTypeArray(attributebitmap);

                IHasReference thisobject = replicatedobjectcontroller.GetEntity(reference);
                if (thisobject == null)
                {
                    LogFile.WriteLine("ObjectModifiedRpc received for unknown object " + reference);
                    return;
                }
                int nextposition = 0;
                new BinaryPacker().UnpackIntoObjectUsingSpecifiedAttributes(entity, ref nextposition,
                    thisobject, new Type[] { typeof(Replicate) });

                LogFile.WriteLine("server received replicated modified object: " + thisobject);
                replicatedobjectcontroller.ReplicatedObjectModified(this,
                    new ObjectModifiedArgs(DateTime.Now, thisobject, AttributeTypeList.ToArray()));
                dirtyobjectcontroller.MarkDirty(thisobject, AttributeTypeList.ToArray());
            }
            else
            {
                LogFile.WriteLine("ObjectModifiedRpcServerToClient " + typename);

                Type modifiedobjecttype = Type.GetType(typename);

                IReplicatedObjectController replicatedobjectcontroller = GetControllerForType(modifiedobjecttype);
                if (replicatedobjectcontroller == null)
                {
                    LogFile.WriteLine("ObjectModifiedRpc. Error: no controller for received type " + typename);
                    return;
                }

                List<Type> AttributeTypeList = new ReplicateAttributeHelper().BitmapToAttributeTypeArray(attributebitmap);

                IHasReference thisobject = replicatedobjectcontroller.GetEntity(reference);
                bool objectisnew = false;
                if (thisobject == null)
                {
                    LogFile.WriteLine("Creating new object");
                    thisobject = Activator.CreateInstance(modifiedobjecttype) as IHasReference;
                    objectisnew = true;
                }
                int nextposition = 0;
                new BinaryPacker().UnpackIntoObjectUsingSpecifiedAttributes(entity, ref nextposition,
                    thisobject, new Type[] { typeof(Replicate) });

                LogFile.WriteLine("client received replicated modified object: " + thisobject);
                if (objectisnew)
                {
                    replicatedobjectcontroller.ReplicatedObjectCreated(this,
                        new ObjectCreatedArgs(DateTime.Now, thisobject));
                }
                else
                {
                    replicatedobjectcontroller.ReplicatedObjectModified(this,
                        new ObjectModifiedArgs(DateTime.Now, thisobject, AttributeTypeList.ToArray()));
                }
            }
        }
        public void ObjectCreatedRpcServerToClient(IPEndPoint connection, int reference, string typename, int attributebitmap, byte[] entitydata)
        {
            LogFile.WriteLine("ObjectCreatedRpcServerToClient " + typename);

            Type newtype = Type.GetType(typename);
            IHasReference newobject = (IHasReference)Activator.CreateInstance(newtype); // note to self: insecure

            IReplicatedObjectController replicatedobjectcontroller = null;
            foreach (Type replicatedtype in objectcontrollers.Keys)
            {
                if (replicatedtype.IsInstanceOfType(newobject))
                {
                    replicatedobjectcontroller = objectcontrollers[replicatedtype];
                }
            }
            if (replicatedobjectcontroller == null)
            {
                LogFile.WriteLine("Error: no controller for received type " + typename);
                return;
            }

            List<Type> AttributeTypeList = new ReplicateAttributeHelper().BitmapToAttributeTypeArray(attributebitmap);

            int nextposition = 0;
            new BinaryPacker().UnpackIntoObjectUsingSpecifiedAttributes(entitydata, ref nextposition,
                newobject, new Type[] { typeof(Replicate) });

            if (!replicatedobjectcontroller.HasEntityForReference(newobject.Reference))
            {
                LogFile.WriteLine("client received replicated object: " + newobject);
                replicatedobjectcontroller.ReplicatedObjectCreated(this,
            new ObjectCreatedArgs(DateTime.Now, newobject)); // note to self: untested cast
            }
        }
        // incoming rpc calls
        // ===================
        public void ObjectCreatedRpcClientToServer(IPEndPoint connection, int remoteclientreference, string typename, int attributebitmap, byte[] entitydata )
        {
            LogFile.WriteLine("ObjectCreatedRpcClientToServer " + typename );

            //LogFile.WriteLine(Encoding.UTF8.GetString(entitydata));

            // note to self: should probably make a whitelist of allowed typenames, maybe via primitive class registration
            Type newtype = Type.GetType(typename);
            IHasReference newobject = (IHasReference) Activator.CreateInstance(newtype);

            IReplicatedObjectController replicatedobjectcontroller = GetControllerForObject( newobject );

            List<Type> AttributeTypeList = new ReplicateAttributeHelper().BitmapToAttributeTypeArray(attributebitmap);

            int nextposition = 0;
            new BinaryPacker().UnpackIntoObjectUsingSpecifiedAttributes(entitydata, ref nextposition,
                newobject, new Type[] { typeof(Replicate) });
            LogFile.WriteLine("server received replicated object: " + newobject.GetType());

            int newobjectreference = 0;
            if (replicatedobjectcontroller != null && replicatedobjectcontroller is IReferenceGenerator)
            {
                newobjectreference = (replicatedobjectcontroller as IReferenceGenerator).GenerateReference();
            }
            else
            {
                newobjectreference = nextreference;
                nextreference++;
            }

            LogFile.WriteLine("New object reference: " + newobjectreference);
            if( newobject is IHasReference )
            {
                ( newobject as IHasReference ).Reference = newobjectreference;
            }

            if (replicatedobjectcontroller != null)
            {
                replicatedobjectcontroller.ReplicatedObjectCreated(this,
            new ObjectCreatedArgs(DateTime.Now, (IHasReference)newobject)); // note to self: untested cast
            }

            new OSMP.NetworkInterfaces.ObjectReplicationServerToClient_ClientProxy( rpc, connection
                ).ObjectCreatedServerToCreatorClient(
                remoteclientreference, newobjectreference );

            dirtyobjectcontroller.MarkDirty(newobject, new Type[] { typeof(Replicate) });
        }