Merge branch 'master' into httptests

UbitUmarov [2016-07-31 22:19:51]
Merge branch 'master' into httptests
Filename
OpenSim/Framework/Util.cs
OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs
OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 1b3a4c3..5250d30 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -368,47 +368,49 @@ namespace OpenSim.Framework
             return Utils.UIntsToLong(X, Y);
         }

-        // Regions are identified with a 'handle' made up of its region coordinates packed into a ulong.
-        // Several places rely on the ability to extract a region's location from its handle.
-        // Note the location is in 'world coordinates' (see below).
-        // Region handles are based on the lowest coordinate of the region so trim the passed x,y to be the regions 0,0.
+        // Regions are identified with a 'handle' made up of its world coordinates packed into a ulong.
+        // Region handles are based on the coordinate of the region corner with lower X and Y
+        // var regions need more work than this to get that right corner from a generic world position
+        // this corner must be on a grid point
         public static ulong RegionWorldLocToHandle(uint X, uint Y)
         {
-            return Utils.UIntsToLong(X, Y);
+           ulong handle = X & 0xffffff00; // make sure it matchs grid coord points.
+           handle <<= 32; // to higher half
+           handle |= (Y & 0xffffff00);
+           return handle;
         }

-        public static ulong RegionLocToHandle(uint X, uint Y)
+        public static ulong RegionGridLocToHandle(uint X, uint Y)
         {
-            return Utils.UIntsToLong(Util.RegionToWorldLoc(X), Util.RegionToWorldLoc(Y));
+            ulong handle = X << 40; // shift to higher half and mult by 256)
+            handle |= (Y << 8);  // mult by 256)
+            return handle;
         }

         public static void RegionHandleToWorldLoc(ulong handle, out uint X, out uint Y)
         {
             X = (uint)(handle >> 32);
-            Y = (uint)(handle & (ulong)uint.MaxValue);
+            Y = (uint)(handle & 0xfffffffful);
         }

         public static void RegionHandleToRegionLoc(ulong handle, out uint X, out uint Y)
         {
-            uint worldX, worldY;
-            RegionHandleToWorldLoc(handle, out worldX, out worldY);
-            X = WorldToRegionLoc(worldX);
-            Y = WorldToRegionLoc(worldY);
+            X = (uint)(handle >> 40) & 0x00ffffffu; //  bring from higher half, divide by 256 and clean
+            Y = (uint)(handle >> 8) & 0x00ffffffu; // divide by 256 and clean
+            // if you trust the uint cast then the clean can be removed.
         }

-        // A region location can be 'world coordinates' (meters from zero) or 'region coordinates'
-        //      (number of regions from zero). This measurement of regions relies on the legacy 256 region size.
-        // These routines exist to make what is being converted explicit so the next person knows what was meant.
-        // Convert a region's 'world coordinate' to its 'region coordinate'.
+        // A region location can be 'world coordinates' (meters) or 'region grid coordinates'
+        // grid coordinates have a fixed step of 256m as defined by viewers
         public static uint WorldToRegionLoc(uint worldCoord)
         {
-            return worldCoord / Constants.RegionSize;
+            return worldCoord >> 8;
         }

-        // Convert a region's 'region coordinate' to its 'world coordinate'.
+        // Convert a region's 'region grid coordinate' to its 'world coordinate'.
         public static uint RegionToWorldLoc(uint regionCoord)
         {
-            return regionCoord * Constants.RegionSize;
+            return regionCoord << 8;
         }

         public static T Clamp<T>(T x, T min, T max)
@@ -1303,7 +1305,7 @@ namespace OpenSim.Framework
                 }
                 catch (Exception e)
                 {
-                    m_log.WarnFormat("[UTILS]: Exception copying configuration file {0} to {1}: {2}", exampleConfigFile, configFile, e.Message);
+                    m_log.WarnFormat("[UTILS]: Exception copying configuration file {0} to {1}: {2}", configFile, exampleConfigFile, e.Message);
                     return false;
                 }
             }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index efc714f..980d3cc 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -1537,8 +1537,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer

         public ScenePresence CrossAsync(ScenePresence agent, bool isFlying)
         {
-            uint x;
-            uint y;
             Vector3 newpos;
             EntityTransferContext ctx = new EntityTransferContext();
             string failureReason;
@@ -1588,7 +1586,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer

             agent.Scene.RequestTeleportLocation(
                 agent.ControllingClient,
-                Util.RegionLocToHandle(regionX, regionY),
+                Util.RegionGridLocToHandle(regionX, regionY),
                 position,
                 agent.Lookat,
                 (uint)Constants.TeleportFlags.ViaLocation);
@@ -1814,7 +1812,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
             // In any case
             agent.IsInTransit = false;

-            m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
+//            m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
         }

         #endregion
@@ -2115,79 +2113,62 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
         //    contains that point. A conservitive estimate.
         private class NotFoundLocationCache
         {
-            private struct NotFoundLocation
-            {
-                public double minX, maxX, minY, maxY;
-                public DateTime expireTime;
-            }
-            private List<NotFoundLocation> m_notFoundLocations = new List<NotFoundLocation>();
+            private Dictionary<ulong, DateTime> m_notFoundLocations = new Dictionary<ulong, DateTime>();
             public NotFoundLocationCache()
             {
             }
-            // Add an area to the list of 'not found' places. The area is the snapped region
-            //    area around the added point.
+            // just use normal regions handlers and sizes
             public void Add(double pX, double pY)
             {
+                ulong psh = (ulong)pX & 0xffffff00ul;
+                psh <<= 32;
+                psh |= (ulong)pY & 0xffffff00ul;
+
                 lock (m_notFoundLocations)
-                {
-                    if (!LockedContains(pX, pY))
-                    {
-                        NotFoundLocation nfl = new NotFoundLocation();
-                        // A not found location is not found for at least a whole region sized area
-                        nfl.minX = pX - (pX % (double)Constants.RegionSize);
-                        nfl.minY = pY - (pY % (double)Constants.RegionSize);
-                        nfl.maxX = nfl.minX + (double)Constants.RegionSize;
-                        nfl.maxY = nfl.minY + (double)Constants.RegionSize;
-                        nfl.expireTime = DateTime.Now + TimeSpan.FromSeconds(30);
-                        m_notFoundLocations.Add(nfl);
-                    }
-                }
-
+                    m_notFoundLocations[psh] = DateTime.Now + TimeSpan.FromSeconds(30);;
             }
             // Test to see of this point is in any of the 'not found' areas.
             // Return 'true' if the point is found inside the 'not found' areas.
             public bool Contains(double pX, double pY)
             {
-                bool ret = false;
+                ulong psh = (ulong)pX & 0xffffff00ul;
+                psh <<= 32;
+                psh |= (ulong)pY & 0xffffff00ul;
+
                 lock (m_notFoundLocations)
-                    ret = LockedContains(pX, pY);
-                return ret;
-            }
-            private bool LockedContains(double pX, double pY)
-            {
-                bool ret = false;
-                this.DoExpiration();
-                foreach (NotFoundLocation nfl in m_notFoundLocations)
                 {
-                    if (pX >= nfl.minX && pX < nfl.maxX && pY >= nfl.minY && pY < nfl.maxY)
+                    if(m_notFoundLocations.ContainsKey(psh))
                     {
-                        ret = true;
-                        break;
+                        if(m_notFoundLocations[psh] > DateTime.UtcNow)
+                            return true;
+                        m_notFoundLocations.Remove(psh);
                     }
+                    return false;
                 }
-                return ret;
             }
+
             private void DoExpiration()
             {
-                List<NotFoundLocation> m_toRemove = null;
-                DateTime now = DateTime.Now;
-                foreach (NotFoundLocation nfl in m_notFoundLocations)
+                List<ulong> m_toRemove = new List<ulong>();;
+                DateTime now = DateTime.UtcNow;
+                lock (m_notFoundLocations)
                 {
-                    if (nfl.expireTime < now)
+                    foreach (KeyValuePair<ulong, DateTime> kvp in m_notFoundLocations)
                     {
-                        if (m_toRemove == null)
-                            m_toRemove = new List<NotFoundLocation>();
-                        m_toRemove.Add(nfl);
+                        if (kvp.Value < now)
+                            m_toRemove.Add(kvp.Key);
+                    }
+
+                    if (m_toRemove.Count > 0)
+                    {
+                        foreach (ulong u in m_toRemove)
+                            m_notFoundLocations.Remove(u);
+                        m_toRemove.Clear();
                     }
-                }
-                if (m_toRemove != null)
-                {
-                    foreach (NotFoundLocation nfl in m_toRemove)
-                        m_notFoundLocations.Remove(nfl);
-                    m_toRemove.Clear();
                 }
             }
         }
+
         #endregion // NotFoundLocationCache class
         private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache();

@@ -2202,10 +2183,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer

         // Given a world position, get the GridRegion info for
         //   the region containing that point.
-        // Someday this should be a method on GridService.
-        // 'pSizeHint' is the size of the source region but since the destination point can be anywhere
-        //     the size of the target region is unknown thus the search area might have to be very large.
-        // Return 'null' if no such region exists.
         protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID,
                             double px, double py, uint pSizeHint)
         {
@@ -2213,11 +2190,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
             GridRegion ret = null;
             const double fudge = 2.0;

-            // One problem with this routine is negative results. That is, this can be called lots of times
-            //   for regions that don't exist. m_notFoundLocationCache remembers 'not found' results so they
-            //   will be quick 'not found's next time.
-            // NotFoundLocationCache is an expiring cache so it will eventually forget about 'not found' and
-            //   thus re-ask the GridService about the location.
             if (m_notFoundLocationCache.Contains(px, py))
             {
 //                m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py);
@@ -2226,60 +2198,45 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer

             // As an optimization, since most regions will be legacy sized regions (256x256), first try to get
             //   the region at the appropriate legacy region location.
-            uint possibleX = (uint)Math.Floor(px);
-            possibleX -= possibleX % Constants.RegionSize;
-            uint possibleY = (uint)Math.Floor(py);
-            possibleY -= possibleY % Constants.RegionSize;
+            // this is all that is needed on 0.9 grids
+            uint possibleX = (uint)px & 0xffffff00u;
+            uint possibleY = (uint)py & 0xffffff00u;
             ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
             if (ret != null)
             {
-                m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
-                                    LogHeader, possibleX, possibleY, ret.RegionName);
+//                m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
+//                                    LogHeader, possibleX, possibleY, ret.RegionName);
+                return ret;
             }

-            if (ret == null)
+            // for 0.8 regions just make a BIG area request. old code whould do it plus 4 more smaller on region open edges
+            // this is what 0.9 grids now do internally
+            List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
+                        (int)(px - Constants.MaximumRegionSize), (int)(px + 1), // +1 bc left mb not part of range
+                        (int)(py - Constants.MaximumRegionSize), (int)(py + 1));
+//          m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
+//                       LogHeader, possibleRegions.Count, range);
+            if (possibleRegions != null && possibleRegions.Count > 0)
             {
-                // If the simple lookup failed, search the larger area for a region that contains this point
-                double range = (double)pSizeHint + fudge;
-                while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
+                // If we found some regions, check to see if the point is within
+                foreach (GridRegion gr in possibleRegions)
                 {
-                    // Get from the grid service a list of regions that might contain this point.
-                    // The region origin will be in the zero direction so only subtract the range.
-                    List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
-                                        (int)(px - range), (int)(px),
-                                        (int)(py - range), (int)(py));
-                    m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
-                                        LogHeader, possibleRegions.Count, range);
-                    if (possibleRegions != null && possibleRegions.Count > 0)
-                    {
-                        // If we found some regions, check to see if the point is within
-                        foreach (GridRegion gr in possibleRegions)
-                        {
-                            m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
-                                                LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
-                            if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
+//                  m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
+//                               LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
+                    if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
                                 && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
-                            {
-                                // Found a region that contains the point
-                                ret = gr;
-                                m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
-                                break;
-                            }
-                        }
+                    {
+                        // Found a region that contains the point
+                        return gr;
+//                      m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
                     }
-                    // Larger search area for next time around if not found
-                    range *= 2;
                 }
             }

-            if (ret == null)
-            {
-                // remember this location was not found so we can quickly not find it next time
-                m_notFoundLocationCache.Add(px, py);
-                m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py);
-            }
-
-            return ret;
+            // remember this location was not found so we can quickly not find it next time
+            m_notFoundLocationCache.Add(px, py);
+//          m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py);
+            return null;
         }

         private void InformClientOfNeighbourCompleted(IAsyncResult iar)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index e3c6c0d..acfdaef 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
         /// <returns>true if the agent was not already in transit, false if it was</returns>
         internal bool SetInTransit(UUID id)
         {
-            m_log.DebugFormat("{0} SetInTransit. agent={1}, newState=Preparing", LogHeader, id);
+//            m_log.DebugFormat("{0} SetInTransit. agent={1}, newState=Preparing", LogHeader, id);
             lock (m_agentsInTransit)
             {
                 if (!m_agentsInTransit.ContainsKey(id))
@@ -123,7 +123,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
         /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
         internal bool UpdateInTransit(UUID id, AgentTransferState newState)
         {
-            m_log.DebugFormat("{0} UpdateInTransit. agent={1}, newState={2}", LogHeader, id, newState);
+ //           m_log.DebugFormat("{0} UpdateInTransit. agent={1}, newState={2}", LogHeader, id, newState);

             bool transitionOkay = false;

@@ -247,32 +247,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
                 {
                     AgentTransferState state = m_agentsInTransit[id];

-                    if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination)
-                    {
+//                    if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination)
+//                    {
                         // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed
                         // to be handled properly - ResetFromTransit() could be invoked at any step along the process
-                        m_log.WarnFormat(
-                            "[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}",
-                            id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName);
+//                        m_log.WarnFormat(
+//                            "[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}",
+//                            id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName);

 //                        throw new Exception(
 //                            "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first",
 //                            state, AgentTransferState.CleaningUp);
-                    }
+//                    }

                     m_agentsInTransit.Remove(id);

-                    m_log.DebugFormat(
-                        "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}",
-                        id, m_mod.Scene.RegionInfo.RegionName);
+//                    m_log.DebugFormat(
+//                        "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}",
+//                        id, m_mod.Scene.RegionInfo.RegionName);

                     return true;
                 }
             }

-            m_log.WarnFormat(
-                "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared",
-                id, m_mod.Scene.RegionInfo.RegionName);
+//            m_log.WarnFormat(
+//                "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared",
+//                id, m_mod.Scene.RegionInfo.RegionName);

             return false;
         }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
index d38ac9b..7d8ae57 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             if (!m_Enabled)
                 return;

-            m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionID);
+            m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionHandle);
             scene.EventManager.OnRegionUp -= OnRegionUp;
         }

@@ -220,16 +220,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
         //     be the base coordinate of the region.
         public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
         {
+
             // try in cache by handler first
-            ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y);
+//            ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y);

             bool inCache = false;
-            GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache);
-            if (inCache)
-                return rinfo;
+//            GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache);
+//            if (inCache)
+//                return rinfo;

-            // try in cache by slower position next
-            rinfo = m_RegionInfoCache.Get(scopeID, x, y, out inCache);
+            GridRegion rinfo = m_RegionInfoCache.Get(scopeID, (uint)x, (uint)y, out inCache);
             if (inCache)
                 return rinfo;

diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs
index 8f3dfc1..6db9515 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs
@@ -44,11 +44,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
 //                LogManager.GetLogger(
 //                MethodBase.GetCurrentMethod().DeclaringType);

-        private RegionsExpiringCache m_Cache;
+        private static RegionsExpiringCache m_Cache;
+        private int numberInstances;

         public RegionInfoCache()
         {
-            m_Cache = new RegionsExpiringCache();
+            if(m_Cache == null)
+                m_Cache = new RegionsExpiringCache();
+            numberInstances++;
         }

         public void Cache(GridRegion rinfo)
@@ -78,8 +81,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             if (rinfo == null)
                 return;

-//            m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS);
-            m_Cache.Add(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); // don't override local regions
+            m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS);
         }

         public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds)
@@ -90,9 +92,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds);
         }

-        public void Remove(UUID scopeID, UUID regionID)
+        public void Remove(UUID scopeID, GridRegion rinfo)
+        {
+            m_Cache.Remove(scopeID, rinfo);
+        }
+
+        public void Remove(UUID scopeID, ulong regionHandle)
         {
-            m_Cache.Remove(scopeID, regionID);
+            m_Cache.Remove(scopeID, regionHandle);
         }

         public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache)
@@ -137,7 +144,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             return null;
         }

-        public GridRegion Get(UUID scopeID, int x, int y, out bool inCache)
+        public GridRegion Get(UUID scopeID, uint x, uint y, out bool inCache)
         {
             inCache = false;

@@ -152,109 +159,285 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
         }
     }

-
-    // following code partialy adapted from lib OpenMetaverse
-    public class RegionKey
+    public class RegionInfoForScope
     {
-        public UUID ScopeID;
-        public UUID RegionID;
+        public const ulong HANDLEMASH = 0xffffff00ffffff00ul;
+        public const ulong HANDLECOORDMASH = 0xffffff00ul;
+
+        private Dictionary<ulong, GridRegion> storage;
+        private Dictionary<ulong, DateTime> expires;
+        private Dictionary<string, ulong> byname;
+        private Dictionary<UUID, ulong> byuuid;

-        public RegionKey(UUID scopeID, UUID id)
+        public RegionInfoForScope()
         {
-            ScopeID = scopeID;
-            RegionID = id;
+            storage = new Dictionary<ulong, GridRegion>();
+            expires = new Dictionary<ulong, DateTime>();
+            byname = new Dictionary<string, ulong>();
+            byuuid = new Dictionary<UUID, ulong>();
         }
-
-        public override int GetHashCode()
+
+        public RegionInfoForScope(GridRegion region, DateTime expire)
         {
-            int hash = ScopeID.GetHashCode();
-            hash += hash * 23 + RegionID.GetHashCode();
-            return hash;
+           storage = new Dictionary<ulong, GridRegion>();
+           expires = new Dictionary<ulong, DateTime>();
+           byname = new Dictionary<string, ulong>();
+           byuuid = new Dictionary<UUID, ulong>();
+
+           ulong handle = region.RegionHandle & HANDLEMASH;
+           storage[handle] = region;
+           expires[handle] = expire;
+           byname[region.RegionName] = handle;
+           byuuid[region.RegionID] = handle;
         }

-        public override bool Equals(Object b)
+        public void Add(GridRegion region, DateTime expire)
         {
-            if(b == null)
-                return false;
-            RegionKey kb = b as RegionKey;
-            return (ScopeID == kb.ScopeID && RegionID == kb.RegionID);
+            ulong handle = region.RegionHandle & HANDLEMASH;
+
+            if(storage != null && storage.ContainsKey(handle))
+                return;
+
+            if(storage == null)
+               storage = new Dictionary<ulong, GridRegion>();
+            if(expires == null)
+               expires = new Dictionary<ulong, DateTime>();
+            if(byname == null)
+                byname = new Dictionary<string, ulong>();
+            if(byuuid == null)
+                byuuid = new Dictionary<UUID, ulong>();
+
+            storage[handle] = region;
+            expires[handle] = expire;
+            byname[region.RegionName] = handle;
+            byuuid[region.RegionID] = handle;
         }
-    }

-    class RegionKeyEqual : EqualityComparer<RegionKey>
-    {
-        public override int GetHashCode(RegionKey rk)
+        public void AddUpdate(GridRegion region, DateTime expire)
         {
-            return rk.GetHashCode();
+            if(storage == null)
+               storage = new Dictionary<ulong, GridRegion>();
+            if(expires == null)
+               expires = new Dictionary<ulong, DateTime>();
+            if(byname == null)
+                byname = new Dictionary<string, ulong>();
+            if(byuuid == null)
+                byuuid = new Dictionary<UUID, ulong>();
+
+            ulong handle = region.RegionHandle & HANDLEMASH;
+
+            storage[handle] = region;
+            if(expires.ContainsKey(handle))
+            {
+                if(expires[handle] < expire)
+                    expires[handle] = expire;
+            }
+            else
+                expires[handle] = expire;
+            byname[region.RegionName] = handle;
+            byuuid[region.RegionID] = handle;
         }

-        public override bool Equals(RegionKey a, RegionKey b)
+        public void Remove(GridRegion region)
         {
-            return (a.ScopeID == b.ScopeID && a.RegionID == b.RegionID);
+            if(region == null)
+                return;
+
+            if(byname != null)
+                byname.Remove(region.RegionName);
+            if(byuuid != null)
+                byuuid.Remove(region.RegionID);
+
+            ulong handle = region.RegionHandle & HANDLEMASH;
+            if(storage != null)
+               storage.Remove(handle);
+            if(expires != null)
+            {
+                expires.Remove(handle);
+                if(expires.Count == 0)
+                    Clear();
+            }
         }
-    }

-    public class RegionInfoByScope
-    {
-        private Dictionary<string, RegionKey> byname;
-        private Dictionary<ulong, RegionKey> byhandle;
+        public void Remove(ulong handle)
+        {
+            handle &= HANDLEMASH;
+
+            if(storage != null)
+            {
+                if(storage.ContainsKey(handle))
+                {
+                    GridRegion r = storage[handle];
+                    if(byname != null)
+                        byname.Remove(r.RegionName);
+                    if(byuuid != null)
+                        byuuid.Remove(r.RegionID);
+                }
+                storage.Remove(handle);
+            }
+            if(expires != null)
+            {
+                expires.Remove(handle);
+                if(expires.Count == 0)
+                    Clear();
+            }
+        }

-        public RegionInfoByScope()
+        public void Clear()
         {
-            byname = new Dictionary<string, RegionKey>();
-            byhandle = new Dictionary<ulong, RegionKey>();
+            if(expires != null)
+                expires.Clear();
+            if(storage != null)
+                storage.Clear();
+            if(byname != null)
+                byname.Clear();
+            if(byuuid != null)
+                byuuid.Clear();
+            byname = null;
+            byuuid = null;
+            storage = null;
+            expires = null;
         }

-        public RegionInfoByScope(GridRegion region, RegionKey key)
+        public bool Contains(GridRegion region)
         {
-           byname = new Dictionary<string, RegionKey>();
-           byhandle = new Dictionary<ulong, RegionKey>();
+            if(storage == null)
+                return false;
+            if(region == null)
+                return false;

-           byname[region.RegionName] = key;
-           byhandle[region.RegionHandle] = key;
+            ulong handle = region.RegionHandle & HANDLEMASH;
+            return storage.ContainsKey(handle);
         }

-        public void AddRegion(GridRegion region, RegionKey key)
+        public bool Contains(ulong handle)
         {
-            if(byname == null)
-                byname = new Dictionary<string, RegionKey>();
-            if(byhandle == null)
-                byhandle = new Dictionary<ulong, RegionKey>();
+            if(storage == null)
+                return false;

-           byname[region.RegionName] = key;
-           byhandle[region.RegionHandle] = key;
+            handle &= HANDLEMASH;
+            return storage.ContainsKey(handle);
         }

-        public void RemoveRegion(GridRegion region)
+        public GridRegion get(ulong handle)
         {
-            if(byname != null)
-                byname.Remove(region.RegionName);
-            if(byhandle != null)
-                byhandle.Remove(region.RegionHandle);
+            if(storage == null)
+                return null;
+
+            handle &= HANDLEMASH;
+            if(storage.ContainsKey(handle))
+                return storage[handle];
+
+            return null;
         }

-        public void Clear()
+        public GridRegion get(string name)
         {
-            if(byname != null)
-                byname.Clear();
-            if(byhandle != null)
-                byhandle.Clear();
-            byname = null;
-            byhandle = null;
+            if(byname == null || !byname.ContainsKey(name))
+                return null;
+
+            ulong handle = byname[name];
+            if(storage.ContainsKey(handle))
+                return storage[handle];
+            return null;
         }

-        public RegionKey get(string name)
+        public GridRegion get(UUID id)
         {
-            if(byname == null || !byname.ContainsKey(name))
+            if(byuuid == null || !byuuid.ContainsKey(id))
                 return null;
-            return byname[name];
+
+            ulong handle = byuuid[id];
+            if(storage.ContainsKey(handle))
+                return storage[handle];
+            return null;
         }

-        public RegionKey get(ulong handle)
+        public GridRegion get(uint x, uint y)
         {
-            if(byhandle == null || !byhandle.ContainsKey(handle))
+            if(storage == null)
                 return null;
-            return byhandle[handle];
+
+            // look for a handle first this should find normal size regions
+            ulong handle = (ulong)x & HANDLECOORDMASH;
+            handle <<= 32;
+            handle |= ((ulong)y & HANDLECOORDMASH);
+
+            if(storage.ContainsKey(handle))
+                return storage[handle];
+
+            // next do the harder work
+            foreach(KeyValuePair<ulong, GridRegion> kvp in storage)
+            {
+                GridRegion r = kvp.Value;
+                if(r == null) // ??
+                    continue;
+
+                int test = r.RegionLocX;
+                if(x < test)
+                    continue;
+                test += r.RegionSizeX;
+                if(x >= test)
+                    continue;
+                test = r.RegionLocY;
+                if (y < test)
+                    continue;
+                test +=  r.RegionSizeY;
+                if (y < test)
+                    return r;
+            }
+            return null;
+        }
+
+        public int expire(DateTime now )
+        {
+            if(expires == null || expires.Count == 0)
+                return 0;
+
+            List<ulong> toexpire = new List<ulong>();
+            foreach(KeyValuePair<ulong, DateTime> kvp in expires)
+            {
+                if(kvp.Value < now)
+                    toexpire.Add(kvp.Key);
+            }
+
+            if(toexpire.Count == 0)
+                return expires.Count;
+
+            if(toexpire.Count == expires.Count)
+            {
+                Clear();
+                return 0;
+            }
+
+            foreach(ulong h in toexpire)
+            {
+                if(storage != null)
+                {
+                    if(storage.ContainsKey(h))
+                    {
+                        GridRegion r = storage[h];
+                        if(byname != null)
+                            byname.Remove(r.RegionName);
+                        if(byuuid != null)
+                            byuuid.Remove(r.RegionID);
+                    }
+                   storage.Remove(h);
+                }
+                if(expires != null)
+                   expires.Remove(h);
+            }
+
+            if(expires.Count == 0)
+            {
+                byname = null;
+                byuuid = null;
+                storage = null;
+                expires = null;
+                return 0;
+            }
+
+            return expires.Count;
         }

         public int Count()
@@ -276,10 +459,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
         /// <summary>For thread safety</summary>
         object isPurging = new object();

-        static RegionKeyEqual keyequal = new RegionKeyEqual();
-        Dictionary<RegionKey, GridRegion> timedStorage = new Dictionary<RegionKey, GridRegion>(keyequal);
-        Dictionary<RegionKey, DateTime> timedExpires = new Dictionary<RegionKey, DateTime>();
-        Dictionary<UUID, RegionInfoByScope> InfobyScope = new Dictionary<UUID, RegionInfoByScope>();
+        Dictionary<UUID, RegionInfoForScope> InfobyScope = new Dictionary<UUID, RegionInfoForScope>();
         private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds);

         public RegionsExpiringCache()
@@ -288,297 +468,225 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             timer.Start();
         }

-        public bool Add(UUID scope, GridRegion region, float expirationSeconds)
+        public bool AddOrUpdate(UUID scope, GridRegion region, float expirationSeconds)
         {
+            if(region == null)
+                return false;
+
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");

-            RegionKey key = new RegionKey(scope , region.RegionID);
-
             try
             {
-                if (timedStorage.ContainsKey(key))
-                    return false;
-
                 DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
-                timedStorage[key] = region;
-                timedExpires[key] = expire;

-                RegionInfoByScope ris = null;
+                RegionInfoForScope ris = null;
                 if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
                 {
-                    ris = new RegionInfoByScope(region, key);
+                    ris = new RegionInfoForScope(region, expire);
                     InfobyScope[scope] = ris;
                 }
                 else
-                    ris.AddRegion(region, key);
+                    ris.AddUpdate(region, expire);

                 return true;
             }
-            finally { Monitor.Exit(syncRoot);}
+            finally { Monitor.Exit(syncRoot); }
         }

-        public bool AddOrUpdate(UUID scope, GridRegion region, float expirationSeconds)
+        public void Clear()
         {
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
-
             try
             {
-                RegionKey key = new RegionKey(scope, region.RegionID);
-                DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
+                foreach(RegionInfoForScope ris in InfobyScope.Values)
+                     ris.Clear();
+                InfobyScope.Clear();
+            }
+            finally { Monitor.Exit(syncRoot); }
+        }
+
+        public bool Contains(UUID scope, GridRegion region)
+        {
+            if(region == null)
+                return false;

-                if (timedStorage.ContainsKey(key))
-                {
-                    timedStorage[key] = region;
-                    if(expire > timedExpires[key])
-                        timedExpires[key] = expire;
+            if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
+                throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");

-                    if(!InfobyScope.ContainsKey(scope))
-                    {
-                        RegionInfoByScope ris = new RegionInfoByScope(region, key);
-                        InfobyScope[scope] = ris;
-                    }
+            try
+            {
+                RegionInfoForScope ris = null;
+                if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
                     return false;
-                }
-                else
-                {
-                    timedStorage[key] = region;
-                    timedExpires[key] = expire;
-                    RegionInfoByScope ris = null;
-                    if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
-                    {
-                        ris = new RegionInfoByScope(region,key);
-                        InfobyScope[scope] = ris;
-                    }
-                    else
-                        ris.AddRegion(region,key);
-                    return true;
-                }
+
+                return ris.Contains(region);
             }
             finally { Monitor.Exit(syncRoot); }
         }

-        public void Clear()
+        public bool Contains(UUID scope, ulong handle)
         {
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
+
             try
-            {
-                timedStorage.Clear();
-                timedExpires.Clear();
-                InfobyScope.Clear();
+            {
+                RegionInfoForScope ris = null;
+                if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
+                    return false;
+
+                return ris.Contains(handle);
             }
             finally { Monitor.Exit(syncRoot); }
         }
-
-        public bool Contains(UUID scope, GridRegion region)
-        {
-            RegionKey key = new RegionKey(scope, region.RegionID);
-            return Contains(key);
-        }

-        public bool Contains(RegionKey key)
+        public int Count()
         {
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
+
             try
-            {
-                return timedStorage.ContainsKey(key);
+            {
+                int count = 0;
+                foreach(RegionInfoForScope ris in InfobyScope.Values)
+                    count += ris.Count();
+                return count;
             }
             finally { Monitor.Exit(syncRoot); }
         }

-        public int Count
-        {
-            get
-            {
-                return timedStorage.Count;
-            }
-        }
-        public bool Remove(UUID scope, GridRegion region)
+        public bool Remove(UUID scope, ulong handle)
         {
-            return Remove(scope, region.RegionID);
-        }
-        public bool Remove(UUID scope, UUID regionID)
-        {
-            RegionKey key = new RegionKey(scope, regionID);
-
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
             try
             {
-                if (timedStorage.ContainsKey(key))
-                {
-                    RegionInfoByScope ris = null;
-                    if(InfobyScope.TryGetValue(scope, out ris) && ris != null)
-                    {
-                        GridRegion r = timedStorage[key];
-                        if(r != null)
-                            ris.RemoveRegion(r);
-                        if(ris.Count() == 0)
-                            InfobyScope.Remove(scope);
-                    }
-                    timedStorage.Remove(key);
-                    timedExpires.Remove(key);
-                    return true;
-                }
-                else
+                RegionInfoForScope ris = null;
+                if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
                     return false;
+
+                ris.Remove(handle);
+                if(ris.Count() == 0)
+                    InfobyScope.Remove(scope);
+                return true;
             }
             finally { Monitor.Exit(syncRoot); }
         }

-        public bool TryGetValue(RegionKey key, out GridRegion value)
+        public bool Remove(UUID scope, GridRegion region)
         {
+            if(region == null)
+                return false;
+
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
             try
-            {
-                if (timedStorage.ContainsKey(key))
-                {
-                    value = timedStorage[key];
-                    return true;
-                }
+            {
+                RegionInfoForScope ris = null;
+                if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
+                    return false;
+
+                ris.Remove(region);
+                if(ris.Count() == 0)
+                    InfobyScope.Remove(scope);
+                return true;
             }
             finally { Monitor.Exit(syncRoot); }
-
-            value = null;
-            return false;
         }

-        public bool TryGetValue(UUID scope, UUID id, out GridRegion value)
+        public bool TryGetValue(UUID scope, ulong handle, out GridRegion value)
         {
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
+
+            value = null;
             try
             {
-                RegionKey rk = new RegionKey(scope, id);
-                if(timedStorage.ContainsKey(rk))
-                {
-                    value = timedStorage[rk];
-                    return true;
-                }
+                RegionInfoForScope ris = null;
+                if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
+                    return false;
+                value = ris.get(handle);
             }
             finally { Monitor.Exit(syncRoot); }

-            value = null;
-            return false;
+            return value != null;
         }

         public bool TryGetValue(UUID scope, string name, out GridRegion value)
         {
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
+
+            value = null;
             try
             {
-                value = null;
-                RegionInfoByScope ris = null;
+                RegionInfoForScope ris = null;
                 if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
                     return false;
-
-                RegionKey key = ris.get(name);
-                if(key == null)
-                    return false;
-
-                if(timedStorage.ContainsKey(key))
-                {
-                    value = timedStorage[key];
-                    return true;
-                }
+                value = ris.get(name);
             }
             finally { Monitor.Exit(syncRoot); }

-            return false;
+            return value != null;
         }

-        public bool TryGetValue(UUID scope, ulong handle, out GridRegion value)
+        public bool TryGetValue(UUID scope, UUID id, out GridRegion value)
         {
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
+
+            value = null;
             try
             {
-                value = null;
-                RegionInfoByScope ris = null;
+                RegionInfoForScope ris = null;
                 if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
                     return false;
-
-                RegionKey key = ris.get(handle);
-                if(key == null)
-                    return false;
-
-                if(timedStorage.ContainsKey(key))
-                {
-                    value = timedStorage[key];
-                    return true;
-                }
+                value = ris.get(id);
             }
             finally { Monitor.Exit(syncRoot); }

-            value = null;
-            return false;
+            return value != null;
         }

         // gets a region that contains world position (x,y)
         // hopefull will not take ages
-        public bool TryGetValue(UUID scope, int x, int y, out GridRegion value)
+        public bool TryGetValue(UUID scope, uint x, uint y, out GridRegion value)
         {
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
+
+            value = null;
             try
             {
-                value = null;
-
-                if(timedStorage.Count == 0)
+                RegionInfoForScope ris = null;
+                if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
                     return false;

-                foreach(KeyValuePair<RegionKey, GridRegion> kvp in timedStorage)
-                {
-                    if(kvp.Key.ScopeID != scope)
-                        continue;
-
-                    GridRegion r = kvp.Value;
-                    if(r == null) // ??
-                        continue;
-                    int test = r.RegionLocX;
-                    if(x < test)
-                        continue;
-                    test += r.RegionSizeX;
-                    if(x >= test)
-                        continue;
-                    test = r.RegionLocY;
-                    if(y < test)
-                        continue;
-                    test += r.RegionSizeY;
-                    if (y < test)
-                    {
-                        value = r;
-                        return true;
-                    }
-                 }
+                value = ris.get(x, y);
             }
             finally { Monitor.Exit(syncRoot); }

-            value = null;
-            return false;
+            return value != null;
         }

         public bool Update(UUID scope, GridRegion region, double expirationSeconds)
         {
+            if(region == null)
+                return false;
+
             if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
                 throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");

-            RegionKey key = new RegionKey(scope, region.RegionID);
             try
             {
-                if (!timedStorage.ContainsKey(key))
+                RegionInfoForScope ris = null;
+                if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
                     return false;

                 DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
-                timedStorage[key] = region;
-                if(expire > timedExpires[key])
-                    timedExpires[key] = expire;
-
+                ris.AddUpdate(region,expire);
                 return true;
             }
             finally { Monitor.Exit(syncRoot); }
@@ -595,7 +703,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             if (!Monitor.TryEnter(isPurging))
                 return;

-            DateTime signalTime = DateTime.UtcNow;
+            DateTime now = DateTime.UtcNow;

             try
             {
@@ -604,32 +712,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
                     return;
                 try
                 {
-                    List<RegionKey> expiredkeys = new List<RegionKey>();
+                    List<UUID> expiredscopes = new List<UUID>();

-                    foreach (KeyValuePair<RegionKey, DateTime> kvp in timedExpires)
+                    foreach (KeyValuePair<UUID, RegionInfoForScope> kvp in InfobyScope)
                     {
-                        if (kvp.Value < signalTime)
-                            expiredkeys.Add(kvp.Key);
+                        if (kvp.Value.expire(now) == 0)
+                            expiredscopes.Add(kvp.Key);
                     }

-                    if (expiredkeys.Count > 0)
+                    if (expiredscopes.Count > 0)
                     {
-                        RegionInfoByScope ris;
-                        foreach (RegionKey key in expiredkeys)
-                        {
-                            ris = null;
-                            if(InfobyScope.TryGetValue(key.ScopeID, out ris) && ris != null)
-                            {
-                                GridRegion r = timedStorage[key];
-                                if(r != null)
-                                    ris.RemoveRegion(r);
-
-                                if(ris.Count() == 0)
-                                    InfobyScope.Remove(key.ScopeID);
-                            }
-                            timedStorage.Remove(key);
-                            timedExpires.Remove(key);
-                        }
+                        foreach (UUID sid in expiredscopes)
+                            InfobyScope.Remove(sid);
                     }
                 }
                 finally { Monitor.Exit(syncRoot); }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
index 96ff4b3..e6e3abb 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
@@ -204,8 +204,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
             if (rinfo != null)
             {
-                m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache from local. Pos=<{1},{2}>, RegionHandle={3}",
-                    rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
+//                m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Found region {0} on local. Pos=<{1},{2}>, RegionHandle={3}",
+//                    rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
                 return rinfo;
             }

@@ -213,16 +213,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid

             if (rinfo == null)
             {
-                uint regionX = Util.WorldToRegionLoc((uint)x);
-                uint regionY = Util.WorldToRegionLoc((uint)y);
-                m_log.WarnFormat("[REMOTE GRID CONNECTOR]: Requested region {0}-{1} not found", regionX, regionY);
+//                uint regionX = Util.WorldToRegionLoc((uint)x);
+//                uint regionY = Util.WorldToRegionLoc((uint)y);
+//                m_log.WarnFormat("[REMOTE GRID CONNECTOR]: Requested region {0}-{1} not found", regionX, regionY);
             }
             else
             {
                 m_RegionInfoCache.Cache(scopeID, rinfo);

-                m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}",
-                    rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
+//                m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}",
+//                    rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
             }
             return rinfo;
         }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 319f14c..e525a2e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -852,19 +852,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             }
         }

-        public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
+        public void osTeleportAgent(string agent, int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
         {
             // High because there is no security check. High griefer potential
             //
             CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");

-            TeleportAgent(agent, regionX, regionY, position, lookat, false);
+            TeleportAgent(agent, regionGridX, regionGridY, position, lookat, false);
         }

-        private void TeleportAgent(string agent, int regionX, int regionY,
+        private void TeleportAgent(string agent, int regionGridX, int regionGridY,
             LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions)
         {
-            ulong regionHandle = Util.RegionLocToHandle((uint)regionX, (uint)regionY);
+            ulong regionHandle = Util.RegionGridLocToHandle((uint)regionGridX, (uint)regionGridY);

             m_host.AddScriptLPS(1);
             UUID agentId = new UUID();
@@ -917,11 +917,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             osTeleportOwner(World.RegionInfo.RegionName, position, lookat);
         }

-        public void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
+        public void osTeleportOwner(int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
         {
             CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");

-            TeleportAgent(m_host.OwnerID.ToString(), regionX, regionY, position, lookat, true);
+            TeleportAgent(m_host.OwnerID.ToString(), regionGridX, regionGridY, position, lookat, true);
         }

         ///<summary>
ViewGit