You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: EntityManager.go
    path of file: ./repos/goworld/engine/entity
    
    the code of the file until where you have to start completion: package entity

import (
	"reflect"

	"strings"

	"github.com/pkg/errors"
	"github.com/xiaonanln/goworld/engine/common"
	"github.com/xiaonanln/goworld/engine/consts"
	"github.com/xiaonanln/goworld/engine/dispatchercluster"
	"github.com/xiaonanln/goworld/engine/gwlog"
	"github.com/xiaonanln/goworld/engine/gwutils"
	"github.com/xiaonanln/goworld/engine/storage"
	"github.com/xiaonanln/typeconv"
)

var (
	registeredEntityTypes = map[string]*EntityTypeDesc{}
	entityManager         = newEntityManager()
)

// EntityTypeDesc is the entity type description for registering entity types
type EntityTypeDesc struct {
	isService       bool
	IsPersistent    bool
	useAOI          bool
	aoiDistance     Coord
	entityType      reflect.Type
	rpcDescs        rpcDescMap
	allClientAttrs  common.StringSet
	clientAttrs     common.StringSet
	persistent
    
func RestoreFreezedEntities(freeze *FreezeData) (err error) {
	defer func() {
		_err := recover()
		if _err != nil {
			err = errors.Wrap(_err.(error), "panic during restore")
		}

	}()

	clients := map[common.EntityID]*GameClient{} // save all the clients when restoring entities
	restoreEntities := func(filter func(typeName string, spaceKind int64) bool) {
		for eid, info := range freeze.Entities {
			typeName := info.Type
			var spaceKind int64
			if typeName == _SPACE_ENTITY_TYPE {
				spaceKind = typeconv.Int(info.Attrs[_SPACE_KIND_ATTR_KEY])
			}

			if filter(typeName, spaceKind) {
				var space *Space
				if typeName != _SPACE_ENTITY_TYPE {
					space = spaceManager.getSpace(info.SpaceID)
				}

				var client *GameClient
				if info.Client != nil {
					client = MakeGameClient(info.Client.ClientID, info.Client.GateID)
					clients[eid] = client // save the Client to the map
					info.Client = nil
				}
				restoreEntity(eid, info, true)
				gwlog.Debugf("Restored %s<%s> in space %s", typeName, eid, space)
			}
		}
	}
	// step 1: restore the nil space
	restoreEntities(func(typeName string, spaceKind int64) bool {
		return typeName == _SPACE_ENTITY_TYPE && spaceKind == 0
	})

	// step 2: restore all other spaces
	restoreEntities(func(typeName string, spaceKind int64) bool {
		return typeName == _SPACE_ENTITY_TYPE && spaceKind != 0
	})

	// step  3: restore all other spaces
	restoreEntities(func(typeName string, spaceKind int64) bool {
		return typeName != _SPACE_ENTITY_TYPE
	})

	// restore clients to all entities
	for eid, client := range clients {
		e := entityManager.get(eid)
		if e != nil {
			e.assignClient(client) // assign Client quietly if migrate
		} else {
			gwlog.Errorf("entity %s restore failed? can not set Client %s", eid, client)
		}
	}

	return nil
}