private void ClientOnParcelInfoRequest(IClientAPI remoteClient, UUID parcelID)
        {
            if (parcelID == UUID.Zero)
                return;

            ExtendedLandData data = (ExtendedLandData)parcelInfoCache.Get(parcelID.ToString(),
                    delegate(string id)
                    {
                        UUID parcel = UUID.Zero;
                        UUID.TryParse(id, out parcel);
                        // assume we've got the parcelID we just computed in RemoteParcelRequest
                        ExtendedLandData extLandData = new ExtendedLandData();
                        Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle,
                                               out extLandData.X, out extLandData.Y);
                        m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
                                          extLandData.RegionHandle, extLandData.X, extLandData.Y);

                        // for this region or for somewhere else?
                        if (extLandData.RegionHandle == m_scene.RegionInfo.RegionHandle)
                        {
                            extLandData.LandData = this.GetLandObject(extLandData.X, extLandData.Y).LandData;
                            extLandData.RegionAccess = m_scene.RegionInfo.AccessLevel;
                        }
                        else
                        {
                            ILandService landService = m_scene.RequestModuleInterface<ILandService>();
                            extLandData.LandData = landService.GetLandData(m_scene.RegionInfo.ScopeID,
                                    extLandData.RegionHandle,
                                    extLandData.X,
                                    extLandData.Y,
                                    out extLandData.RegionAccess);
                            if (extLandData.LandData == null)
                            {
                                // we didn't find the region/land => don't cache
                                return null;
                            }
                        }
                        return extLandData;
                    });

            if (data != null)  // if we found some data, send it
            {
                GridRegion info;
                if (data.RegionHandle == m_scene.RegionInfo.RegionHandle)
                {
                    info = new GridRegion(m_scene.RegionInfo);
                }
                else
                {
                    // most likely still cached from building the extLandData entry
                    uint x = 0, y = 0;
                    Utils.LongToUInts(data.RegionHandle, out x, out y);
                    info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y);
                }
                // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark.
                m_log.DebugFormat("[LAND MANAGEMENT MODULE]: got parcelinfo for parcel {0} in region {1}; sending...",
                                  data.LandData.Name, data.RegionHandle);
                // HACK for now
                RegionInfo r = new RegionInfo();
                r.RegionName = info.RegionName;
                r.RegionLocX = (uint)info.RegionLocX;
                r.RegionLocY = (uint)info.RegionLocY;
                r.RegionSettings.Maturity = (int)Util.ConvertAccessLevelToMaturity(data.RegionAccess);
                remoteClient.SendParcelInfo(r, data.LandData, parcelID, data.X, data.Y);
            }
            else
                m_log.Debug("[LAND MANAGEMENT MODULE]: got no parcelinfo; not sending");
        }
        private ExtendedLandData ParcelNotFound(IClientAPI remoteClient)
        {
            LandData landData = new LandData();
            landData.Name = "Land Parcel Not Found";
            landData.Description = "This land parcel could not be found: the region may be down or no longer be part of the grid.\n\n"
                                 + "(The current region has been substituted for this Search result.)";

            ExtendedLandData extLandData = new ExtendedLandData();
            extLandData.landData = landData;
            extLandData.regionHandle = m_scene.RegionInfo.RegionHandle;
            extLandData.x = 128; 
            extLandData.y = 128;

            // Fill in the current position of the avatar to prevent a beacon from appearing on Show On Map
            ScenePresence SP = m_scene.GetScenePresence(remoteClient.AgentId);
            if (SP != null)
            {
                Vector3 pos = SP.AbsolutePosition;
                extLandData.x = (uint)pos.X;
                extLandData.y = (uint)pos.Y;
            }

            return extLandData;
        }
        private ExtendedLandData QueryParcelID(UUID parcelID)
        {
            ExtendedLandData extData = null;

            using (ISimpleDB db = _connFactory.GetConnection())
            {
                // See of the parcel ID is a real one defined in the land table (e.g. from a Places search).
                string query = "select land.RegionUUID, land.LocalLandID from land where land.UUID=?parcelID";
                Dictionary<string, object> parms = new Dictionary<string, object>();
                parms.Add("?parcelID", parcelID.ToString());

                List<Dictionary<string, string>> results = DoLandQueryAndCombine(db, query, parms);
                if (results.Count > 1)
                    m_log.ErrorFormat("[Land]: Found {0} results searching for parcel ID {1}", results.Count, parcelID.ToString());
                if (results.Count > 0)
                {
                    LandData landData = null;
                    ulong regionHandle = 0;

                    Dictionary<string, string> row = results[0];
                    int localLandID = Convert.ToInt32(row["LocalLandID"]);
                    UUID regionID = new UUID(row["RegionUUID"].ToString());

                    // for this region or for somewhere else?
                    if (regionID == m_scene.RegionInfo.RegionID)
                    {
                        ILandObject parcel = this.GetLandObject(localLandID);
                        if ((parcel != null) && (parcel.landData != null))
                            landData = parcel.landData;
                        regionHandle = m_scene.RegionInfo.RegionHandle;
                    }
                    else
                    {
                        RegionInfo info = m_scene.CommsManager.GridService.RequestNeighbourInfo(regionID);
                        if (info != null)
                        {
                            landData = m_scene.CommsManager.GridService.RequestLandData(info.RegionHandle, localLandID);
                            regionHandle = info.RegionHandle;
                        }
                    }

                    if (landData != null)
                    {
                        extData = new ExtendedLandData();
                        extData.regionHandle = regionHandle;
                        extData.landData = landData;
                        // Prefer the parcel-specified landing area if available, even if set to Anywhere.
                        extData.x = (uint)landData.UserLocation.X;
                        extData.y = (uint)landData.UserLocation.Y;
                        if ((extData.x == 0) && (extData.x == 0))
                        {
                            Vector3 where = AnyParcelLocation(landData);
                            extData.x = (uint)where.X;
                            extData.y = (uint)where.Y;
                        }
                    }
                }
            }
            return extData;
        }
        private ExtendedLandData QueryFakeParcelID(UUID parcelID)
        {
            LandData landData = null;
            ulong regionHandle = 0;
            uint posx = 0;
            uint posy = 0;

            // We didn't find the specified parcel ID so attempt to interpret it as a fake parcel ID.
            Util.ParseFakeParcelID(parcelID, out regionHandle, out posx, out posy);

            // m_log.DebugFormat("[LAND]: got parcelinfo request for regionHandle {0}, x/y {1}/{2}", extLandData.regionHandle, extLandData.x, extLandData.y);

            // for this region or for somewhere else?
            if (regionHandle == m_scene.RegionInfo.RegionHandle)
            {
                ILandObject parcel = this.GetLandObject(posx, posy);
                if (parcel != null)
                    landData = parcel.landData;
            }
            else
                landData = m_scene.CommsManager.GridService.RequestLandData(regionHandle, posx, posy);

            if (landData == null)
                return null;

            ExtendedLandData extLandData = new ExtendedLandData();
            extLandData.landData = landData;
            extLandData.regionHandle = regionHandle;
            extLandData.x = posx;
            extLandData.y = posy;
            return extLandData;
        }
        private void handleParcelInfo(IClientAPI remoteClient, UUID parcelID)
        {
            if (parcelID == UUID.Zero)
                return;

            ExtendedLandData data = (ExtendedLandData)parcelInfoCache.Get(parcelID.ToString(), delegate(string id) {
                UUID parcel = UUID.Zero;
                UUID.TryParse(id, out parcel);
                // assume we've got the parcelID we just computed in RemoteParcelRequest
                ExtendedLandData extLandData = new ExtendedLandData();
                Util.ParseFakeParcelID(parcel, out extLandData.regionHandle, out extLandData.x, out extLandData.y);
                m_log.DebugFormat("[LAND] got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
                                  extLandData.regionHandle, extLandData.x, extLandData.y);

                // for this region or for somewhere else?
                if (extLandData.regionHandle == m_scene.RegionInfo.RegionHandle)
                {
                    extLandData.landData = this.GetLandObject(extLandData.x, extLandData.y).landData;
                }
                else
                {
                    extLandData.landData = m_scene.CommsManager.GridService.RequestLandData(extLandData.regionHandle,
                                                                                            extLandData.x,
                                                                                            extLandData.y);
                    if (extLandData.landData == null)
                    {
                        // we didn't find the region/land => don't cache
                        return null;
                    }
                }
                return extLandData;
            });

            if (data != null)  // if we found some data, send it
            {
                RegionInfo info;
                if (data.regionHandle == m_scene.RegionInfo.RegionHandle)
                {
                    info = m_scene.RegionInfo;
                }
                else
                {
                    // most likely still cached from building the extLandData entry
                    info = m_scene.CommsManager.GridService.RequestNeighbourInfo(data.regionHandle);
                }
                // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark.
                m_log.DebugFormat("[LAND] got parcelinfo for parcel {0} in region {1}; sending...",
                                  data.landData.Name, data.regionHandle);
                remoteClient.SendParcelInfo(info, data.landData, parcelID, data.x, data.y);
            }
            else
                m_log.Debug("[LAND] got no parcelinfo; not sending");
        }