In a Page Visitor Tracking web part I have been writing, I use the SPSecurity.RunWithElevatedPrivileges function to add or update a line in a Visitor Tracking list on the current site.  The idea being that not all visitors to the page will have the rights to write to this list, so some level of impersonation is needed.
 
Frustratingly, even though I had used this function to elevate the privileges of the current user, I was still getting an "Access Denied" message when running the functionality under my test user.
 
After a bit of searching on the net (great entry by Daniel Larson - http://daniellarson.spaces.live.com/blog/cns!D3543C5837291E93!927.entry?sa=486500840), I determined that the problem was that I was getting my reference to the list whilst the code was still running under the current users context, and not the elevated user.
 
e.g. (Note, this code sample has been cut down a great deal to illustrate the point - no "try...catch" blocks, for example.  It should be used only as a guide, and not copied to be used as is)
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

protected override void CreateChildControls()
{
    //Get the current web
   
SPWeb web = SPControl.GetContextWeb(Context);

    //Get the list to record visits
   
visList = web.Lists[_visitorList];

    //See if this user already exists in list
   
_existItemId = GetVisitorItemId(visList);

    //If not in list, add them
   
if (_existItemId == 0)
    {
       
//Run the AddCurrentUserToList function with elevated priv's
      
SPSecurity.CodeToRunElevated elevatedAddCurrentUserToList = new SPSecurity.CodeToRunElevated(AddCurrentUserToList);

        SPSecurity.RunWithElevatedPrivileges(elevatedAddCurrentUserToList);
    }
   else
   
{
       
//Run the AddCurrentUserToList function with elevated priv's
       
SPSecurity.CodeToRunElevated elevatedIncrementNumberOfVisits = new SPSecurity.CodeToRunElevated(IncrementNumberOfVisits);

        SPSecurity.RunWithElevatedPrivileges(elevatedIncrementNumberOfVisits);
    }
}


private
void AddCurrentUserToList()

{
   
//Create new ListItem
   
SPListItemCollection items = visList.Items;
    SPListItem newItem = items.Add();

    //Set field values for new ListItem

    //Update Item
    newItem.Update();
}


private
void IncrementNumberOfVisits()

{
    //Get the ListItem to update

    //Increment the number of visits

    //Update the item
   
updateItem.Update();
}

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Because of this, I changed my code so that I made a new reference to the SPWeb in the elevated code block, and obtained a new reference to the list:


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

protected override void CreateChildControls()
{
   
//Get the current web
   
SPWeb web = SPControl.GetContextWeb(Context);
    _curWeb = web.Url;

    SPList visList = null;

    //Get the list to record visits
   
visList = web.Lists[_visitorList];

    //See if this user already exists in list
   
_existItemId = GetVisitorItemId(visList);

    //If not in list, add them
   
if (_existItemId == 0)
    {
       
//Run the AddCurrentUserToList function with elevated priv's
       
SPSecurity.CodeToRunElevated elevatedAddCurrentUserToList = new SPSecurity.CodeToRunElevated(AddCurrentUserToList);

        SPSecurity.RunWithElevatedPrivileges(elevatedAddCurrentUserToList);
    }
   
else
   
{
       
//Run the AddCurrentUserToList function with elevated priv's
       
SPSecurity.CodeToRunElevated elevatedIncrementNumberOfVisits = new SPSecurity.CodeToRunElevated(IncrementNumberOfVisits);

        SPSecurity.RunWithElevatedPrivileges(elevatedIncrementNumberOfVisits);
    }
}


private
void AddCurrentUserToList()

{
   
//Get list
   
SPSite site = new SPSite(_curWeb);
    SPWeb web = site.OpenWeb();
    SPList visList = web.Lists[_visitorList];

    web.AllowUnsafeUpdates = true;

     //Create new ListItem
    
SPListItemCollection items = visList.Items;
    SPListItem newItem = items.Add();

    //Set field values for new ListItem

    //Update Item
    newItem.Update();

    web.AllowUnsafeUpdates = false;

    //Cleanup
   
web.Dispose();
    site.Dispose();
}

 

private void IncrementNumberOfVisits()
{
   
//Get list
   
SPSite site = new SPSite(_curWeb);
    SPWeb web = site.OpenWeb();
    SPList visList = web.Lists[_visitorList];

    web.AllowUnsafeUpdates = true;

    //Get the ListItem to update

    //Increment the number of visits

    //Update the item
   
updateItem.Update();

    web.AllowUnsafeUpdates = false;

    //Cleanup
   
web.Dispose();
    site.Dispose();
}

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
SPList's, SPWeb's etc get the identity of the user context they are created under associated with them for their entire lifetime.  Like most things, seems obvious once you understand it.
 
To get around this, I no longer use the SPList globally, but instead keep the URL of the web globally, and use this in the elevated code blocks to derive an SPSite, SPWeb and finally the required SPList.
 
Important to note that this as the SPWeb that I create in the elevated code block is a different SPWeb to what I am using outside this block (it has the SHAREPOINT\Security identity associated with it, not the current users) it can (and should) safely disposed of from within this block.

-----------------------------------------------------------

UPDATE:  As can be seen in the comments below,
Keith Dahlby has posted a much more elegant way of achieving the elevation of privileges by using the site's token.

I have changed my code to follow this (and incorporated the functionality in my SharePoint.Common library) and recommend reading his article - see http://solutionizing.net/2009/01/06/elegant-spsite-elevation/

Keep up the good work Keith!