Tuesday, February 14, 2017
NPI Now (beta) - http://www.npinow.com
While I cannot get into specifics because of the proprietary nature of the process, I can say the goal of NPI Now is to provide pharma, medical device, and any companies participating in Open Payments, peace of mind when submitting data to CMS. When data is submitted to CMS, the final step is an officer of the reporting company personally attesting to the accuracy of the data. That's a big risk so who wouldn't want an additional level of comfort that the data is accurate?
In addition to searching for physician data, NPI Now provides API services for your organization. The API can be used as a lookup of NPI data with additional SAGA scoring data. We also offer batch NPI data based on specific criteria like taxonomy codes or the entire set. Our NPI data is updated weekly to ensure the latest data is processed and available. Additional NPI data specifications are available upon request.
Finally, we provide an augmented list of over 800 taxonomy codes with ID's, categories, and titles. We include the deprecated taxonomy codes since CMS often removes them from reporting. However, few people know about these changes and they typically don't know about the change until the data fails when uploaded during the CMS reporting month.
What makes us experts? I have over 10-years of aggregate spend and CMS Open Payments experience. I spent the majority of that time working with Top 10 pharma companies. In addition to being a top analyst in the industry, I have developed several applications and processes to facilitate and validate the collection and reporting of aggregate spend data. I have also served as Submitter of data into the CMS Open Payments systems. I know what makes good data, but I really know what makes bad data!
Back on Blogger!
I have started a could of small Internet startups and wanted a place to talk about them outside the realm of Twitter and Facebook. In addition to talking business, I'll talk about going to school online, some development stuff, and whatever else comes to mind.
All the posts before this one are dated and some of them make me want to travel back in time and punch myself in the face. Thanks!
Monday, April 05, 2010
This blog has moved
This blog is now located at http://ernestcarroll.blogspot.com/.
You will be automatically redirected in 30 seconds, or you may click here.
For feed subscribers, please update your feed subscriptions to
http://ernestcarroll.blogspot.com/feeds/posts/default.
Sunday, April 04, 2010
Gmail-esque Purely CSS Gradient Buttons
Google's Gmail uses webkit to generate gradient buttons for their Archive, Report Spam, etc buttons. While that's fine for some browsers it won't work with IE. For IE they use div elements with some slick CSS code. I've attempted to recreate what Gmail does, but with considerably less code. These buttons will look great in most modern browsers and will scale perfectly using your browser's zoom feature.
<style type="text/css">
body, div {margin: 0px; padding: 0px; font-size: 12pt; }
body { margin: 1em; }
div { font-family: arial; font-size: 88%; }
/* control width with another div container */
.wrapper { width: 600px; }
.border_left { border-left: solid 1px #fff !important; }
.last { margin-right: 1em; }
.button_container
{
float: left;
position: relative;
border: solid 1px #bbb;
overflow: hidden;
line-height: 1.8em;
height: 1.8em;
background-color: #efefef;
cursor: pointer;
}
.button_top
{
position: absolute;
top: 0px;
left: 0px;
right: 0px;
height: 0.9em;
border-bottom: solid 2px #f7f7f7;
background-color: #fff;
line-height: 0.9em;
width: 100%;
}
.button_bottom
{
position: absolute;
top: 0px;
left: 0px;
right: 0px;
padding-left: 1em;
padding-right: 1em;
text-align: center;
height: 100%;
white-space: nowrap;
line-height: 1.8em;
}
.arrow
{
background: url(images.png) no-repeat -36px 50%;
width: 7px;
}
</style>
My div buttons require just 3 divs, but I've included a fourth, wrapper class, to give some structure as the buttons are designed to use 100% width without it. I also include some simple CSS reset code to get rid of margins and whatnot.
This button_container class gives me the outer border and sets the size (height, line-height) of the button. Make sure overflow: hidden is set to hide elements that may otherwise be unruly.
Each button is actually two stacked divs. Since I use relative positioning in button_container, the absolute positions used in button_top and button_bottom will use button_container's top, left, and right coordinates. There is also a 2px bottom border on button_top to give a clean, gradient-like, effect when viewing the button.
Finally, the arrow class will display the dropdown arrow in a span.
<div class="wrapper">
<div class="button_container" style="width: 68px">
<div class="button_top"> </div>
<div class="button_bottom">
<b>Archive</b>
</div>
</div>
<div class="button_container border_left" style="width: 88px;">
<div class="button_top"> </div>
<div class="button_bottom">
<span>Report Spam</span>
</div>
</div>
<div class="button_container border_left" style="width: 56px;">
<div class="button_top"> </div>
<div class="button_bottom">
<span>Delete</span>
</div>
</div>
<div class="button_container border_left last" style="width: 90px;">
<div class="button_top"> </div>
<div class="button_bottom">
<span>Mark as read</span>
</div>
</div>
<div class="button_container" style="width: 72px">
<div class="button_top"> </div>
<div class="button_bottom">
<span>Move to</span>
<span class="arrow"> </span>
</div>
</div>
<div class="button_container border_left last" style="width: 66px;">
<div class="button_top"> </div>
<div class="button_bottom">
<span>Labels</span>
<span class="arrow"> </span>
</div>
</div>
<div class="button_container last" style="width: 96px">
<div class="button_top"> </div>
<div class="button_bottom">
<span>More actions</span>
<span class="arrow"> </span>
</div>
</div>
</div>
The final result looks like this in IE8:

Even if you like the look of images, these buttons will give you a professional looking layout while you code your application. Root around the code and check it out for yourself. Let me know what you think!
Sunday, January 03, 2010
N900 Tethering Via iPhone 3G
I first scanned for wifi connections and there were plenty available. Many of them were open as well which would make things easy, but the easy road isn't always challenging. I wanted to try something different.
My iPhone is jailbroken with PdaNet installed. For those who don't know, PdaNet is a shareware application that allows you to tether your iPhone's Internet connection. There are two modes available: WiFi Router Mode and USB Mode. USB Mode wouldn't work for me since that requires PdaNet desktop installed on a PC. WiFi Router Mode requires the connecting device, in this case the N900, to create an ad hoc wifi network. This happens to be very simple to setup on the N900 much to my delight.
On the N900 go to Settings > Internet Connections. Click on the Connections button and click New. A prompt will come up asking you to tap Next to continue. After doing so, we finally get to the Connection Setup. For the Connection Name I entered N900, but you can enter anything you like. Click Next and the N900 will ask you to scan for WiFi networks, click No. The next series of questions go into more detail:
Connection Setup: Wi-Fi
Network name (SSID): pdanet
Network is hidden: Unchecked
Network mode: Ad hoc
Security method: None
Save your settings and return to desktop. Click the Battery, Clock, Time in the top bar and click Internet Connections. Your new connection will appear as N900 (if you named the new wifi connection that). Be sure to click on it and return to the iPhone.
On the iPhone, open PdaNet and check WiFi Router Mode and click Done. PdaNet will scan for a connection in which your N900 will appear as it's SSID, pdanet (if you followed my example). Press the name once it appears and PdaNet will connect. Now you can return to your N900 device and do whatever tinkering you need to do using your iPhone's 3G connection. Fulfilling and satisfying, isn't it?
PdaNet is one of many tethering apps for the iPhone. I chose it because it was the only one that worked when I was looking to tether my phone. But feel free to use similar settings with the other (free) tethering apps out there. Finally, be sure to turn off PdaNet WiFi Router Mode when you are done surfing on your N900 to conserve battery on your iPhone.
Thursday, December 31, 2009
N900 Bluetooth DUN on AT&T
Setup is easy. On the N900, download and setup the app via Application Manager. Done.
Pair your phone with your Mac which makes available Bluetooth PAN and Bluetooth DUN network adapters. Using the Bluetooth DUN adapter enter the settings shown in the screenshot below. The Password is CINGULAR1.

In Advanced Settings I have the following options under the Modem tab:

Press Okay after making your changes and press Connect. Voila! You're connected and surfing through your N900.
Nokia N900 Review
Speed
Unfortunately, when I bought my N900 I just expected it would work on AT&T's 3G network in the US. I was wrong and should have checked the N900's specs. Nokia really missed the ball on this one if they intended selling these in the US. I'm hoping they have something up their sleeve. While 2.5 isn't terrible I find my iPhone's 3G loads browser pages slightly faster, which is to be expected. The only option for US users is T-Mobile if they want the 3G experience. YMMV when it comes to T-Mobile's coverage.
Wireless setup and speeds are similar to any other device. I set mine up in a few seconds after finding the Internet Connection option under Settings.
The N900 scores an A if you're on T-Mobile, B for AT&T.
Touchscreen
As we know there are two types of touchscreen most common in handheld devices, capacitive and restrictive. A capacitive touchscreen recognizes touches using the electric impulse from your finger, i.e. iPhone or iPod Touch screen. A restrictive screen uses the pressure of your finger or stylus (yuk!). In my opinion, restrictive screens are passe. It's unfortunate that the N900 has one. I find it unresponsive compared to what I am used to with the iPhone. However, I have found a happy medium in that I can use my finger nail to achieve rather accurate touches. I refuse to use the stylus since it's not 1999. Do Treo's still exist?
All-in-all, I'd give the screen a B-.
Keyboard
You have two options here. One is the onscreen keyboard. While it's effective using the fingernail technique, it doesn't always popup when you enter a text field. Annoying! Which leads me to the slide out keyboard. The full query keyboard is nicely laid out and the custom keys are very intuitive. I find typing on it somewhat difficult when attempting to strike keys on the first row. I have large, not mutant large, but large hands and struggle to strike those keys with any consistency. I would have preferred another 1/8 inch or a slide out similar to the n97.
I think this the slide out is another just-miss for the N900 and give it a B-.
Camera
The N900 hit gold with the cameras. Not only do they work well they are highly configurable. 5MP in high resolution and 3MP in widescreen with integrated flash plus all the modes you would expect from a pre-SLR digital camera appear to be there.
The video camera in the N900 is excellent as well. I found the videos to be quite smooth and crisp. The good news is theres also a camera in front of the camera. While Nokia does not support that camera yet, one of the upcoming firmwares are sure to. Does this mean video conferencing is coming to an N900 near you? I hope so.
This score is simple, A+!
Apps
The app count just hit 100 as of New Year's Eve, but this device is still very new. The open Linux-based Maemo OS has lots of promise but let's hope we get some robust applications and not hundreds of small console-based niche apps I see in most Linux repositories. The best thing to do is to turn on the dev-extras repository under Application Manager. With this repo you can browse dozens of apps still under development.
I can't put a score on this one so I'll have to check back and see where we are with apps after Q1 2010.
Happy New Year!
Sunday, June 21, 2009
Lua Code Completion for Notepad++
Wednesday, May 06, 2009
Canceling MySpace Account

I never use MySpace and never real had an attraction to the site. Tom, you made your money, but now it's time to clear the way for Facebook and Twitter. I enjoyed the three levels of confirmation I had to go through to cancel. It's interesting that even after multiple confirmations I still have check my email to finish the process. This is the Columbo of account cancellations.
Monday, July 14, 2008
iPhone post
Monday, May 12, 2008
CSS Horizontal Menu with Submenu
I was playing with some CSS code over the weekend. My goal was to make a cross-browser compatible horizontally tabbed menu using HTML's unordered list tag. This concept has been beaten into the ground pretty well on the web, but none of the solutions I found fit my needs.
- CSS menu file: menu.css
- Sample HTML: cssExample.html
The code here has been successfully testing in Internet Explorer 6.0 and Mozilla Firefox 2.0. Notice I did not need to use CSS conditionals for IE compatibility. I though that was a nice touch :)
CSS Code:
#menu ul {
border-bottom: solid 1px #336699;
font: normal normal bold 14px verdana;
margin: 0;
margin-top: .1em;
padding: 4px 0; /* This typically corresponds to the padding-top value in '#menu li a' */
text-align: left;
}
#menu li {
list-style: none;
display: inline;
margin: 0;
}
#menu li a {
background: #EFEFEF;
border: solid 1px #336699;
border-bottom: none;
color: #336699;
margin-right: 0em;
padding: 4px 6px;
text-decoration: none;
}
#menu li a:hover {
background: #FFF;
}
#menu li a.last {
border-right: solid 1px #336699;
}
#menu li a.selected {
background: #FFF;
border-bottom: solid 1px #FFF;
}
#submenu ul {
height: 1em;
list-style: none;
padding: 3px 0;
margin: 0;
border-bottom: solid 1px #336699;
}
#submenu li {
display: inline;
}
#submenu li a {
float: left;
padding: 3px 7px;
margin: 0;
font: normal normal bold 10px verdana;
border-right: solid 1px #EEE;
color: #336699;
text-decoration: none;
}
#submenu li a:hover {
text-decoration: underline;
}
#submenu li a.last {
border-right: none;
}
HTML Code:
<div id="menu">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Client</a></li>
<li><a href="#">Download</a></li>
<li><a href="#" class="selected">Support</a></li>
<li><a href="#" class="last">Forum</a></li> </ul>
</div>
<div id="submenu">
<ul>
<li><a href="#">Live Chat</a></li>
<li><a href="#">Phone</a></li>
<li><a href="#" class="last">Email</a></li>
</ul>
</div>
Consider this the base code. You can easily manipulate the functionality with PHP, C#, and JavaScript.
cssExample.htmlFriday, February 08, 2008
Web-based Chat, AMPchat 2.0!
If you would like to try AMPchat 2.0 while in BETA for free. Please leave a comment and we'll get back to you.
Video Sharing Application
Some of the features include "bumping" videos (a rating system), leaving comments, creating user profiles, sharing videos with friends, and more.
Leave a comment if you would like to beta test the application for free, of course.
Friday, September 14, 2007
Changing environments from VS.NET 2005 to Visual Web Developer 2005 Express
What makes a great gaming store?
I was thinking what would make a good game store. Corporations have diluted the personal touch you used to get at games stores of old. The local GameStop of EB Games (now the same company) tend to have the usual, low paid, teens at the counter. They usually know some games, but don't know much about the more obscure games.
Most of the stores make their living off of trade-ins. The trade-in value is extremely low becuase they know you are at their mercy. Markup is usually 100% or more on consoles, and I believe games are close to that. Take the GameCube for example. The trade-in value is currently 10 bucks, but if you go to buy one it's usually around $75. Not that anybody wants one anymore, but parents looking for a less costly alternative to the more popular systems find these prices quite attractive while purchasing them. I wonder if they feel ripped on when trading them in? What's more, who is setting the values for trade-ins? Is there a blue book for them?
I think 3 things are key to a game store:
- Knowledgeable staff. They still exist! Gaming is so mainstream now, most don't smell. The customers experience must be that the people know what they are talking about, and are excited about it.
- Selection. Games, consoles, accessories... you better have them.
- Demos. Being able to try out games before you buy them is ciritical. Everytime I read a good review still always wonder who wrote the review and if they like the sames things I do about games. Being able to try a console is another great way to help make your decision. I hear many people tell me they don't like what they ordered online. Well, don't be lazy and go try one out before you drop four or five hundred.
What else would make a game store better?
Sunday, May 20, 2007
Friday, April 27, 2007
Wednesday, November 08, 2006
DropDownList in GridView
The problem I encountered was being able to use an updateable GridView using data from multiple tables. The two main tables are called Category and Forum. A forum can only belong to one category, but a category can contain multiple forums. To make things a bit more difficult, I used a associative table to relate the two called CategoryForum.
My goal is to be able to manage my forums without have to know the category ID of each category. It should be simple enough for a novice to use. My architectural solution had several components. Of course, I had the GridView. Then I had two ObjectDataSources using a web service to return forum and category data. The forum data includes a category ID via an INNER JOIN in the query. The category data is just the list of all categories.
First, I override the Page's OnInitComplete method to capture the update event:
1: protected override void OnInitComplete(EventArgs e)
2: {3: base.OnInitComplete(e);
4: gridView.RowUpdating +=5: new GridViewUpdateEventHandler(gridView_RowUpdating);
6: }Next, I wrote some code for the overridden method. This code will store my DropDownList's data in the updating data objects field:
void gridView_RowUpdating(Object sender, GridViewUpdateEventArgs e) {
int index = gridView.EditIndex;
GridViewRow row = gridView.Rows[index];
DropDownList categoryDropDown =
(DropDownList) row.FindControl("ddlCategoryName");
e.NewValues["CategoryId"] =
int.Parse(categoryDropDown.SelectedValue);
} That's all the code-behind code I needed. In design view I have two ObjectDataSources wired up to a web service that simply delivers a DataSet to each. One DataSet is my Forum data, and the other is Category data. Here's the EditItemTemplate code for the DropDownList. The datasource for the GridView is the ForumData. I used the Category datasource for the DropDownList.
<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
<ItemTemplate>
<%# Eval("CategoryName") %>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList runat="server"
ID="ddlCategoryName" DataTextField="CategoryName"
DataValueField="CategoryId" DataSourceID="objCategories" />
</EditItemTemplate>
</asp:TemplateField>
Encrypting/Decrypting QueryStrings In .NET
I was messing around with a secure way to pass data via a querystring today. In business you sometimes don't have a choice. What I came up with was a secure two-way encryption/decryption class. I can now encode/decode any piece of data without having knowledge of the key.
The Methods
I have an error page in an ASP.NET application. The page is basically going to act as a catch all page for errors in my forum application. I want to be able to send it exception strings without having to rely upon Server.GetLastError. I researched some of the System.Security.Cryptography namespace for a seed-based algorithm. DES seemed to fit that bill perfectly. MSDN even went so far as to write the Encrypt and Decrypt methods for me.
1 // Encrypt the string.
2 public byte[] Encrypt(string PlainText, SymmetricAlgorithm key)
3 {
4 // Create a memory stream.
5 MemoryStream ms = new MemoryStream();
6
7 // Create a CryptoStream using the memory stream and the
8 // CSP DES key.
9 CryptoStream encStream = new CryptoStream(ms, key.CreateEncryptor()
10 CryptoStreamMode.Write);
11
12 // Create a StreamWriter to write a string
13 // to the stream.
14 StreamWriter sw = new StreamWriter(encStream);
15
16 // Write the plaintext to the stream.
17 sw.WriteLine(PlainText);
18
19 // Close the StreamWriter and CryptoStream.
20 sw.Close();
21 encStream.Close();
22
23 // Get an array of bytes that represents
24 // the memory stream.
25 byte[] buffer = ms.ToArray();
26
27 // Close the memory stream.
28 ms.Close();
29
30 // Return the encrypted byte array.
31 return buffer;
32 }
33
34 // Decrypt the byte array.
35 public string Decrypt(byte[] CypherText, SymmetricAlgorithm key)
36 {
37 // Create a memory stream to the passed buffer.
38 MemoryStream ms = new MemoryStream(CypherText);
39
40 // Create a CryptoStream using the memory stream and the
41 // CSP DES key.
42 CryptoStream encStream = new CryptoStream(ms, key.CreateDecryptor(),
43 CryptoStreamMode.Read);
44
45 // Create a StreamReader for reading the stream.
46 StreamReader sr = new StreamReader(encStream);
47
48 // Read the stream as a string.
49 string val = sr.ReadLine();
50
51 // Close the streams.
52 sr.Close();
53 encStream.Close();
54 ms.Close();
55
56 return val;
57 }
This is a great start if I wanted byte arrays. I need to flatten this array out so I can use it like a string. I decided to write a couple more methods named EncryptToString and DecryptToString.
1 public string EncryptToString(string PlainText, SymmetricAlgorithm key)
2 {
3 byte[] buffer = this.Encrypt(PlainText, key);
4 string temp = string.Empty;
5
6 for (int i = 0; i < buffer.Length; i++)
7 {
8 temp += buffer[i].ToString("x2");
9 }
10
11 return temp;
12 }
13
14 public string DecryptFromString(string CypherText, SymmetricAlgorithm key)
15 {
16 int arrayLen = (CypherText.Length / 2);
17 byte[] buffer = new byte[arrayLen];
18
19 for (int i = 0; i < (CypherText.Length / 2); i++)
20 {
21 buffer[i] = Convert.ToByte(Convert.ToInt32(CypherText.Substring(i * 2, 2), 16));
22 }
23
24 return this.Decrypt(buffer, key);
25 }
These methods simply use the two that MSDN provided, but add some app-centric features. EncryptToString will get the byte array from the Encrypt method. Then it will create, and append to, a string while converting each item in the byte array to a two-digit hexadecimal number. The reason I converted to hex was to shorten the total length of the string. A handy byproduct was that it added yet another layer of obfuscation to my data making that much more difficult to decrypt. DecryptFromString takes the encrypted string and essentially reverses the process.
What about the key?
This is my favorite part of the entire solution. The key is generated as an application level variable in the Global.asax. I have to admit that I don't use the Global.asax that much, but it seemed like a reasonable place for the code to generate the key.
1 void Application_Start(object sender, EventArgs e)
2 {
3 DESCryptoServiceProvider key = new DESCryptoServiceProvider();
4 Application.Add("SecureKey", key);
5 }
Of course, this could have been Session level, but I didn't need to change the key that frequently. When adding this code to your page be sure to import the namespace, <%@ Import Namespace="System.Security.Cryptography" %>.
In Action
The final piece is how we would use this in the code. Another reason I went this route was to simplify what I needed to code when using this class. In this example, we have made reference to the class containing the encryption/decryption methods. I called mine, Crypto. We'll be encoding an Exception string and sending it to an error page.
1 Crypto cryptKeeper = new Crypto();
2 string encryptedText = cryptKeeper.EncryptToString(
3 new Exception("The request could not be completed.").ToString(),
4 Application["SecureKey"] as System.Security.Cryptography.SymmetricAlgorithm);
5
6 Response.Redirect("~\\Error.aspx?msg=" + encryptedText);
The encryptedText variable looks something like this, 6998d04ec523b093fe0ce9ce9994915a076199ef1f1663d3273e23
72cb5b53dea83f931016f58dc9ae21a4f335de16038eecaee374cacc28. The error page takes the parameter and decrypts it.
1 Crypto cryptKeeper = new Crypto();
2 if (Request.Params["msg"] != null)
3 {
4 lblMsg.Text = cryptKeeper.DecryptFromString(Request.Params["msg"],
5 Application["SecureKey"] as SymmetricAlgorithm);
6 }
Notes
Because I made my key an Application variable, it will be the same for every user of the site and only change when the site is restarted. If I were to make it a Session variable, it would change for every user, and that may be the way to go for me in the future.
I think the possibilities with this are endless. You don't have to use it to pass secure data via a querystring. It can be used to securely store data in your database. You can code your app to generate and store the DES key daily, weekly, or monthly. Access levels to data should be setup to only allow authorized personnel access to the key table. It's not so much different than what my company spent $50,000 on.
Error When Writing to Custom Event Log
I was getting an error when attempting to write to a custom Event Log on Server 2003 from an ASP page. It looked something like this:
Cannot open log for source 'someSource'. You may not have write access.
The solution was to change the security descriptor on the custom event log's key. I did this by browsing to the custom log's folder in registry, HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Eventlog\<Custom Event Log>. In that folder there will be a key named CustomSD. Double-click the key to open it up for editing.
O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)
The section highlighted in red denies Read, Write, and Clear access to the log for Anonymous logons (AN) and Built-in guests (BG). This explicit deny overrode any other access I attempted to add to the string.
In order to grant my ASP permission to write to the log, I had to make some modifications. The IUSR account is part of two groups, Users and Guests. With Guests and Anonymous being denied, I now knew I needed to grant them access to this log. A couple of searches on MSDN brought up a full description of the SDDL (Security Descriptor Description Language).
Let's dissect the string (D;;0xf0007;;;AN). The 'D' that appears in the descriptor means 'Access Denied.' The 0xf00007 is hex that will basically deny any type of access currently available. I changed the string to explicitly grant write access to Anonymous logons, (A;;0x2;;;AN). The access rights are your cumulative rights where Read = 1, Write = 2, and Clear = 4. The hexadecimal value of 0x2 evaluates to 2 in decimal which is write access.
After making the change to that string and a similar one to (D;;0xf0007;;;BG) my string looked like:
O:BAG:SYD:(A;;0x2;;;AN)(A;;0x2;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)
I refreshed my test ASP page and the error was gone. I didn't have to reboot or restart IIS.
References
