mike-obrien.net Resume Blog Labs
Monday, July 16, 2007

The Stopwatch Class, another great .NET 2.0 feature I keep forgetting to use so I'll blog about it (And hopefully I'll remember ;)... This is a great class for performance monitoring, instead of declaring a start time and subtracting it from the end time, etc. The following snippet checks the performance difference in doing a square root and a tangent over a number of iterations. Internally, when the stopwatch is started, the ticks of the current time are set as the start timestamp. When it is stopped the start ticks and end ticks (Current time) are subtracted and the private elapsed time field (A Long) is updated. The elapsed field is only reset when you explicitly call Reset() as it is accumulative. The public Elapsed property conveniently returns a TimeSpan.

int iterations = 10000000;

 

Stopwatch stopwatch = new Stopwatch();

stopwatch.Start();

 

// Do something...

for (int index = 0; index < iterations; index++)

{ Math.Sqrt(index); }

 

stopwatch.Stop();

 

Console.WriteLine(string.Format("Square root took {0} " +

    "milliseconds for {1} iterations.",

    stopwatch.Elapsed.Milliseconds, iterations));

 

// Do something else...

stopwatch.Reset();

stopwatch.Start();

 

for (int index = 0; index < iterations; index++)

{ Math.Tan(index); }

 

stopwatch.Stop();

 

Console.WriteLine(string.Format(@"Tangent took {0} " +

    "milliseconds for {1} iterations.",

    stopwatch.Elapsed.Milliseconds, iterations));

 

Console.ReadKey();

Monday, July 16, 2007 4:19:51 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Friday, July 13, 2007

An unhandled exception of type 'Microsoft.SharePoint.SPException' occurred in Microsoft.SharePoint.dll

Additional information: One or more field types are not installed properly. Go to the list settings page to delete these fields.

If your getting this exception you may be incorrectly referring to fields that have a space or other special character in them. WSS encodes some characters using a _x0000_ format where the green zeros are the Unicode code point in hex of the character, left padded to four zeros. For example if you had a field called "Default Location" you would call it by its "encoded" version "Default_x0020_Location" where _x0020_ represents the space. You can also learn the underlying name of the field by using the Solution Generator and viewing the list definition:

<List Title="ContactAddressList" Description="" Direction="0" BaseType="0" Url="Lists/ContactAddressList" FolderCreation="FALSE" Version="7" Type="100" xmlns="http://schemas.microsoft.com/sharepoint/">
<!--
_filecategory="ListDefinition" _filetype="Schema" _filename="schema.xml" _uniqueid="ea6eba9f-017b-4d49-bfdb-25f050d080d2" -->
<
MetaData>
      ...
     <Fields>
          ...
          <Field Type="Boolean" DisplayName="Default Location" Name="Default_x0020_Location" ID="{27183229-947f-47fc-bbf9-5659a0f2f3da}" SourceID="{0317159b-0d76-41eb-a257-761888e76903}" StaticName="Default_x0020_Location" ColName="bit1" RowOrdinal="0">
                 <
Default>1</Default>

          </Field>
         ...

     </Fields>
      ...
   </MetaData>
</
List>
Friday, July 13, 2007 6:21:10 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 

I have seen a lot of posts on this and they all say something along the lines of 'simply go and set the path to the base vhd...'. Well, being a Virtual Server user, it wasn't as obvious to do as it is with VPC.  To do it in VS you need to...

1) Copy the VS 2008 VM to a folder in your VS2005 path and add it.

2) Copy the base VM (Which can be downloaded here) to a folder in your VS2005 path.

image

3) Under "Virtual Disks" click "Inspect", select the VS2008 vhd and click "Inspect".

image

4) The "Parent virtual hard disk(s)" property will show a link indicating that the parent drive could not be found. Click this link to set the location of the drive.

image

image

5) Once selected, click "Update parent path", start the VM and Login with administrator/P2ssw0rd.

Friday, July 13, 2007 4:24:51 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Wednesday, July 11, 2007

Someone asked me how to enable the (Fully functioning) web designer in a class library. Honestly I think using a WAP is all you need to do. It will give you a fully functioning web designer and will generate a DLL. If you already have a class library project that you want to now add web pages and user controls too just follow the instructions here (Under the section "Creating a hybrid VSeWSS/WAP Project") but instead add the following ProjectTypeGuids element below (In green). This will turn your class library project into a WAP.

<PropertyGroup>

<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

<ProductVersion>8.0.50727</ProductVersion>

<SchemaVersion>2.0</SchemaVersion>

<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

<ProjectGuid>{26E7042F-79CF-4782-86E2-7D1C914E164A}</ProjectGuid>

<OutputType>Library</OutputType>

<AppDesignerFolder>Properties</AppDesignerFolder>

<RootNamespace>ClassLibraryWithWebDevelopment</RootNamespace>

<AssemblyName>ClassLibraryWithWebDevelopment</AssemblyName>

</PropertyGroup>

Wednesday, July 11, 2007 5:03:30 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Friday, July 06, 2007

Attached is a simple contact generator (And source) that creates random contact data in CSV format. The data generated, although random, is pretty realistic as address and phone numbers correspond correctly and other values are sampled from a realistic set of data. The data generated appears as follows:

"Index","Id","FirstName","LastName","FullName","Username","Username2","Password","Email1","Email2","Phone1","Phone2","Fax1","Fax2","Address1","City1","State1","Zip1","Address2","City2","State2","Zip2"
"1","{c0d4079c-50c7-4214-a094-b09d51b9d143}","Raven","Huddle","Raven Huddle","rhuddle","raven.huddle","13af04ae","raven.huddle@aol.com","raven.huddle@earthlink.net","(303) 998-8084","(718) 229-7963","(303) 998-5593","(718) 229-4928","84596 Brimm BLVD","Boulder","CO","80302","36863 Noakes LN","Flushing","NY","11364"
"2","{74e80927-a654-4010-9020-7098452b4193}","Rhonda","Reitz","Rhonda Reitz","rreitz","rhonda.reitz","3282e152","rhonda.reitz@btinternet.com","rhonda.reitz@verizon.net","(907) 252-0297","(703) 242-6715","(907) 252-0163","(703) 242-9363","89079 Sterrett PL","Soldotna","AK","99669","41346 Mccauley HWY","Vienna","VA","22181"
"3","{742a3ad4-e1e8-44ed-a6a0-1654981e0c9b}","Ruth","Mcnemar","Ruth Mcnemar","rmcnemar","ruth.mcnemar","16548a78","rmcnemar@aol.com","rmcnemar@verizon.net","(305) 541-2410","(704) 892-5466","(305) 541-4633","(704) 892-3899","93562 Bruno BLVD","Miami","FL","33129","45829 Meadowview HWY","Davidson","NC","28036"
"4","{d72fb280-66cf-49a8-81bb-f5da4a096614}","Jimmy","Kizer","Jimmy Kizer","jkizer","jimmy.kizer","3528671c","jkizer@verizon.net","jimmy.kizer@earthlink.net","(704) 854-4523","(734) 797-4218","(704) 854-9102","(734) 797-8335","98044 Meadows HWY, Suite 370","Gastonia","NC","28054","50311 Pamona LN","Livonia","MI","48150"
"5","{90409c90-c967-4b1f-b66c-6b9f31043303}","Kiehl","Gillum","Kiehl Gillum","kgillum","kiehl.gillum","18fa1042","kiehl.gillum@gmail.com","kiehl.gillum@rediffmail.com","(320) 679-6636","(810) 863-2970","(320) 679-3672","(810) 863-2871","2578 Claywood BLVD","Mora","MN","55051","54794 Rockledge PKWY, Suite 945","Roseville","MI","48035"
"6","{f47a479c-d0a9-43d8-84aa-97970b0c4892}","Walletta","Spivey","Walletta Spivey","wspivey","walletta.spivey","37cdece6","wspivey@hotmail.com","wspivey@bellsouth.net","(218) 723-8749","(650) 357-1721","(218) 723-8142","(650) 357-7306","7061 Baypointe AVE","Duluth","MN","55802","59277 Mack HWY","San Mateo","CA","94403"
"7","{f2b1687a-78ce-437b-baa0-2b959ee260d5}","Chauncey","Slemp","Chauncey Slemp","cslemp","chauncey.slemp","1b9f960c","cslemp@comcast.net","cslemp@charter.net","(412) 393-0962","(916) 492-0473","(412) 393-2712","(916) 492-1842","11544 Dumesnil CIR","Pittsburgh","PA","15222","63760 Tiburon PL, Suite 814","Sacramento","CA","95814"
"8","{19189dab-e300-42d2-8580-c4216fcaafb3}","Roxanne","Bond","Roxanne Bond","rbond","roxanne.bond","3a7372b0","roxanne.bond@msn.com","roxanne.bond@aol.com","(336) 506-3075","(308) 652-9124","(336) 506-7181","(308) 652-6278","16027 Continental CIR","Burlington","NC","27215","68242 Burning BLVD","Orleans","NE","67647"
"9","{7703a831-1f56-43cd-87ea-c998fcb52682}","Elvie","Cissell","Elvie Cissell","ecissell","elvie.cissell","1e451bd6","elvie.cissell@charter.net","ecissell@cox.net","(917) 344-5189","(770) 242-7876","(917) 344-1751","(770) 242-0814","20509 Tivoli RD, Suite 491","New York","NY","10041","72725 Perlman LN","Norcross","GA","30071"
"10","{0aed5fd3-70e8-41e0-bbc4-418d122a590b}","Newman","Peters","Newman Peters","npeters","newman.peters","216c4fb","npeters@earthlink.net","npeters@hotmail.com","(719) 530-7302","(281) 944-6628","(719) 530-6221","(281) 944-5249","24992 Oak LN","Salida","CO","81201","77208 Bolsa BLVD","Houston","TX","77037"

Installer: SetupContactGenerator.EXE (833.81 KB)

Source: ContactGeneratorSource.zip (584.5 KB)

Friday, July 06, 2007 3:29:07 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Thursday, July 05, 2007

I must say, the OOB development experience in SharePoint has been less than desirable. I feel like MS has given us a number of tools but left us in the lurch figuring out how to use them, and its not always obvious how. One thing I have wanted to do is use the designer to develop web parts and deploy them with the click of a button. The VSeWSS have made the "deploy with the click of the button" part possible but the designer part has not been so obvious. How can you marry a designer experience with the VSeWSS ease of solution deployment? I'll show you how...

For Starters

The following information utilizes the Visual Studio Extensions for WSS (VSeWSS) which can be downloaded here. VSeWSS only offers a subset of the features available with solution deployment but offers "one touch" deployment OOB. Creating your own solutions manually will give you more options but may be more work than its worth (Unless you have found some nifty 3rd party tool or created your own). So the following information will strictly use what VSeWSS has to offer. VSeWSS can only run on a Windows Server 2003 box with MOSS 2007 & Visual Studio 2005 installed (Although it can be hacked to run on XP, most of the features do not work). VSeWSS may have problems if MOSS 2007 was not installed as a standalone server, so says the download notes and my experience with it. Although I have a colleague who has used it in a farm configuration and not had an issue.

Creating a blank VSeWSS Project & Web Part

Obviously you cant use the designer with a web part but you can with a Web User Control (This is the thought behind SmartParts). So lets start off by creating a project from an empty VSeWSS template.

image

Next add a new Web Part from the VSeWSS templates.

image

Now your probably thinking "Now add a Web User Control, yada yada yada", right? Wrong! If you have gone down this path before you will probably discover a couple of things; first the Web User Control is not available as a new item in a VSeWSS project. This can be worked around fairly easily by modifying the templates available to the class library project type or by creating the user control in a Web Application Project (WAP) and copy the files over, either way hacky. Second, you will discover that the designer does not behave as it does in a WAP or web site. For example your code behind and designer classes are not linked together and when you double click a control the default event code is generated in the ascx file instead of the code behind. This and a number of other quirks render this method almost as bad as just coding your entire control in the Web Part (Almost, but not quite). So how do we get the designer to work properly? .

Creating a hybrid VSeWSS/WAP Project

We need to create a hybrid VSeWSS/WAP project. This requires that you either have VS2005 SP1 installed or the WAP extensions installed (If you decided not to wait 5 hours for SP1 to install...). In order to make your VSeWSS project also a WAP project you will need to adjust the project type in the .xxproj file. To do this, right click the project we just created an select "Unload Project". It may ask you to save, press yes.

image

Once the project is unloaded, right click it again and select "Edit xxxxxxxxxxx.xxproj".

image

Once you have opened the project file you will need to add in the WAP guid into the ProjectTypeGuids element under the first PropertyGroup. This guid, {349c5851-65df-11da-9384-00065b846f21}, should be the second guid in the list (Shown in bold/green below), the first one being the VSeWSS project guid. All the guids in this element should be separated by a semicolon as shown below.

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>

    <ProductVersion>8.0.50727</ProductVersion>

    <SchemaVersion>2.0</SchemaVersion>

    <ProjectGuid>{7A3CF036-DC02-4868-8CBA-A88E75552372}</ProjectGuid>

    <ProjectTypeGuids>{9E5D3E2D-E4E2-418e-8D80-2F0DA9A94F9A};{349c5851-65df-11da-9384-00065b846f21};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

    <OutputType>Library</OutputType>

    <RootNamespace>MyGroovySharePointLibrary</RootNamespace>

    <AssemblyName>MyGroovySharePointLibrary</AssemblyName>

    <SignAssembly>true</SignAssembly>

    <AssemblyOriginatorKeyFile>Properties\Temporary.snk</AssemblyOriginatorKeyFile>

  </PropertyGroup>

 After this has been set, right click the the project again and select "Reload Project". Click yes to save when prompted.

image

Now close out of Visual Studio, save your project when prompted. Restart Visual Studio and open your project.

VSeWSS Deployment

Now your probably thinking "Now add a Web User Control, yada yada yada", right? Well, yes, you can now add a Web User Control and its designer will work properly. But we want to be able to deploy it strictly with VSeWSS and its solution builder. In order to do this we will need to install the user control with a Module, so lets do that first. Right click your project and add a new Module. I will generically call it UserControls as I will want to add more user controls to it as I add web parts.

image

Once your module is created you can delete the "sample.txt" file from the UserControls folder. Now right click the UserControls folder and click Add --> New Item and select the standard Web User Control.

image

Next open the module.xml in the UserControls folder and add a reference to your newly created user control.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Name="UserControls" Url="UserControls" Path="">

    <File Url="MyGroovyUserControl.ascx" />

  </Module>

</Elements>

The Url attribute in the Module element specifies the relative path on the SharePoint site where the file will be deployed to. In this case I chose a sub folder called "UserControls".

Creating the User Control and Linking the Web Part

Now, add a label to your User Control called CurrentTime (Or whatever you want to call it...). And set it, in the control load event, to the current time.

namespace MyGroovySharePointLibrary.UserControls

{

    public partial class MyGroovyUserControl : System.Web.UI.UserControl

    {

        protected void Page_Load(object sender, EventArgs e)

        {

            CurrentTime.Text = DateTime.Now.ToString();

        }

    }

}

Since the VSeWSS Solution Builder creates a solution that installs only the project assembly to the GAC (Which is lame indeed) you will need to add an assembly directive to the user control, before the control directive is defined. If you do not add it before the control directive your control will fail to load as it will not have a reference to the project assembly in the GAC.

<%@ Assembly Name="MyGroovySharePointLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5" %>

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyGroovyUserControl.ascx.cs" Inherits="MyGroovySharePointLibrary.UserControls.MyGroovyUserControl" %>

<asp:Label ID="CurrentTime" runat="server" Text="Label"></asp:Label>

To obtain the public key token you can run the sn.exe utility in the SDK with the -T parameter and the path to the assembly. For example:

image

Next, override the CreateChildControls method of your web part and load the user control with the Page.LoadControl method. UPDATE: Thanks to Charles for pointing out that you also need to remove (If your not using it) the default Render(...) override. The WebPart template has this defined and by default it does not call the base implementation so ya get nothing displayed!

namespace MyGroovyWebPart

{

    [Guid("cc2a1b52-324a-4a20-bca8-0d512f8348b4")]

    public class MyGroovyWebPart :

        System.Web.UI.WebControls.WebParts.WebPart

    {

        public MyGroovyWebPart()

        {

            this.ExportMode = WebPartExportMode.All;

        }

 

        protected override void CreateChildControls()

        {

            string userControl = "/UserControls/MyGroovyUserControl.ascx";

            try

            {

                Controls.Add(this.Page.LoadControl(userControl));

            }

            catch (Exception exception)

            {

                string message = string.Format("{0} failed to load: {1}",

                    userControl,

                    exception.Message);

                Controls.Add(new LiteralControl(message));

            }

        }

    }

}

Now hit F5 and deploy!

image

As you can see, this method gives you the benefit of the designer and VSeWSS solution deployment. The full source of the sample can be downloaded here:

MyGroovySharePointLibrary.zip (417.78 KB)
Thursday, July 05, 2007 5:18:06 AM (GMT Standard Time, UTC+00:00)  #   |  Comments [8]  | 
Tuesday, June 26, 2007

Normally I like to create a stand alone, abstract BLL assembly that can be used by multiple components (ASP.NET, WinForms, Windows Service, etc), nothing new, standard procedure. Well the VSeWSS Solution builder will only load and reference the VSeWSS project assembly in the SharePoint Solution. Pretty lame if you ask me! You would think that it would package all referenced assemblies not just the project assembly, how hard is that?? So you ether have to house all your code in the VSeWSS assembly or deploy referenced assemblies separately to the SP web front ends. If you forget about this, any code that tries to call code in the referenced assembly will throw a generic "File Not Found" exception in SP.

I sincerely hope there is a newer version of VSeWSS coming down the pike. It has the potential to be a really great tool for SP development but the limitations I keep encountering are seriously lessening its value. This is just another example of that.

Tuesday, June 26, 2007 8:42:04 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 

At some point you may want to define an "icon" for your SharePoint list templates. Doing this is kindof quirky and the SDK doesn't seem to mention the quirk (At least I couldn't find it anywhere).

Basically icons will appear in a few places, for example the Create page when you hover over the list and the the site content summary page.

image

image

You can define an image to be displayed in the VSeWSS Solution Properties as shown below:

image

Here I am referencing a 16x16 png called INotice.png. Now for the quirky part... The image path set above will be referenced as-is in the site content summary page (The first image show above) where the small image (16x16) is used. But how do you define the larger image (32x32) used in the Create List form (Show above)? Basically the Create List page takes the url entered into the list Element Manifest Image property above (Which corresponds to the Image attribute of the ListTemplate element in the List template manifest file) and replaces the first letter of the filename with an "L". So it would change the image url above to "/PhvenEleaseResources/LNotice.png". In this case you would see a broken image link when you hovered over your list template.

So you need to deploy 2 images, first a small image (16x16) with some arbitrary prefix character like "I" ("I" is the prefix used by OOB small SharePoint images, but it can be any character), for example "IMyListImage.gif". Set the Image URL in the VSeWSS list element manifest (As shown above), for example "/MyImages/IMyListImage.gif". Additionally, deploy a large image (32x32) that has the same name as your small image but starts with an "L" instead, for example "LMyListImage.gif". SharePoint will then correctly display the large and small images appropriately.

Now, you may be asking, how do I deploy those list images using VSeWSS and Solution Deployment? The best way I could find (Using only VSeWSS) is to create a module. 

image

Once created, remove the sample file and reference from the new module. Copy your list images into the the new module folder and reference them in the module definition as demonstrated below.

<?xml version="1.0" encoding="utf-8"?>

<!-- _filecategory="Module" _filetype="File" _filename="module.xml" _uniqueid="7d203b86-3fe2-46cb-ba36-bb255430ce6f" -->

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

    <Module Name="MyImages" Url="MyImages" RootWebOnly="TRUE">

        <File Url="LMyListImage.gif" Type="Ghostable"/> <!-- Large image (32x32) -->

        <File Url="IMyListImage.gif" Type="Ghostable"/> <!-- Small image (16x16) -->

    </Module>

</Elements>

Once deployed the two images can be referenced as "/MyImages/IMyListImage.gif" and "/MyImages/LMyListImage.gif" where the Module Url attribute defines the path off the root of the site.

Tuesday, June 26, 2007 4:16:17 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Monday, June 25, 2007

If you have worked with VSeWSS templates you will have probably noticed the comment added to the top of certain aspx/xml files:

<!-- _filecategory="ListDefinition" _filetype="File" _filename="editform.aspx" _uniqueid="0cfa6bc5-6fe6-47c2-b557-9b0f56475962" -->

First of all don't delete this! This "comment" is actually meta data that enables the VSeWSS solution builder to process the file. The "_filecategory" property identifies the file category (I have a gift for stating the obvious...). It is actually tied the the SolutionElementFileCategory in the SPDevTools.dll library under the Microsoft.SharePoint.Tools.SharePointSolutions namespace.

public enum SolutionElementFileCategory
{
    Unknown,
    SiteDefinition,
    ListDefinition,
    ListInstance,
    Module,
    ContentType,
    Provisioner
}

Next, the "_filetype" identifies the type of file (Duh!) and is tied to the SolutionElementFileType enumeration in the library/namespace mentioned previously.

public enum SolutionElementFileType
{
    Unknown,
    Schema,
    File
}

Next, the "_filename" property tells the solution builder what the name of the file should be in the resulting solution. And last but not least the guid which uniquely identifies the file. Every element in a solution must have a unique guid in order for the solution builder to work with it ("Element" meaning a SP Solution aspx/xml file or a class). Classes are given a unique identifier by defining a Guid attribute to the class. If you copy an existing aspx/xml solution file, as a template for a new file, remember to change the guid. Also if you are copying a solution file as a template for a new module file don't forget to remove the meta data. If you don't, the solution builder will not include it in the module as it thinks the file has another purpose because of the metadata.

Monday, June 25, 2007 5:50:00 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Friday, June 22, 2007

Another SharePoint anomaly... Will they ever end??? So I have had this strange issue where doing a deploy of a VSeWSS project does not seem to update the SharePoint site for certain elements like schemas. I have to retract/remove the solution manually from SP, close/reopen Visual Studio (Otherwise I would get a null ref error), then redeploy to see changes. The VSeWSS deploy process does an iisreset (Which I tried manually doing as well) but the updates do not appear without following the steps mentioned. I checked the SP database and SP hive and the elements in question were deployed... So the only thing I could think of is that these elements must cached in memory, which was baffling since an iisreset should clear that out (Right?). Well I finally got the bright idea to verify that iisreset was in fact closing out the IIS service process completely. And lo an behold it was not! After further investigation I found that the “Windows Remote Management (WS-Management)” service, which depends on IIS, was preventing a complete exit of the inetinfo process. I'm not sure what the iisreset was actually doing all along (It said it successfully reset the IIS services), possibly just recycling the AppDomain(s)? But in that case wouldn't SP release cached elements upon termination of the AppDomain(s)? Not really sure, but what I am sure of is that stopping and disabling the the WRM service allowed inetinfo to completely close when the service was restarted by iisreset. And voilà! My changes!

Incidentally I am running Virtual Server 2005 which is monitored by the "Virtual Machine Manager Agent" service. This service depends on the WRM service. So disabling the WRM service will disable your VMMA service. You might want to let your network admin know you need this disabled or it might reappear.

Friday, June 22, 2007 9:22:26 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  |