"I'm not sure how he did it," writes Joey, "but one of my colleagues convinced management that we needed a trouble ticketing system. Since we had been using email and post-it notes for many years, it was a welcome addition to the team. Well, at least it would have been... had it not been a home-grown system written by Chad."

"The good news was that Chad had previous experience building such a system. The masterpiece of his previous job was a trouble ticketing system written entirely in VBScript that ran inside of Excel. After several attempts to make it work for us (it had a bad habit of only working on very specific versions of Excel) he decided to start clean using PHP and MySQL. A web-based system was a welcome alternative to a spreadsheet... at least, it would have been had Chad not recently learned about a 'new technology' called AJAX.

"As it turned out, his 'week or two' estimate was a little too optimistic, and it took a solid eight months of mostly full-time work on the system before it was ready for production. Well, his definition of ready. It had countless odd bugs like forms disappearing, lists not populating correctly, edits not actually saving, and so on. After a few weeks of trying to use Chad's software, we just went back to the old email and post-it note system.

"Eventually, Chad left the company, and the higher ups asked me what it would take to make the system actually useful. I told them I would look at the code and see if I could help. One of the first bits I found was this.

function stateChangedbb()
  } catch (e) {

"The function name was a bit curious, and I noticed there were several similarly named functions. So I looked a little deeper.

$ grep -i "function statechanged" *

ajaxlogin.js:function stateChangedcc()
ajaxlogin.js:function stateChanged()
CreateTicketMenu.js:function stateChangedf()
CreateTicketMenu.js:function stateChangedsss()
CreateTicketMenu.js:function stateChangedg()
CreateTicketMenu.js:function stateChangedbb()
CreateTicketMenu.js:function stateChangede()
EquipmentMenu.js:function stateChangedr()
EquipmentMenu.js:function stateChangeds()
EquipmentMenu.js:function stateChangedt()
EquipmentMenu.js:  function stateChangedu()
functions.js:function stateChangedd()
functions.js:function stateChangedk()
functions.js:function stateChangeduu()
functions.js:function stateChangedoo()
functions.js:function stateChangedmm()
functions.js:function stateChangedc()
functions.js:function stateChangedsu()
functions.js:function stateChangedst()
functions.js:function stateChangedsv()
functions.js:function stateChangedrr()
functions.js:function stateChangedb()
functions.js:function stateChangeda()
LocationsMenu.js:function stateChangedl()
LocationsMenu.js:function stateChangedm()
LocationsMenu.js:function stateChangedn()
LocationsMenu.js:function stateChangedo()
LocationsMenu.js:function stateChangedp()
LocationsMenu.js:function stateChangedq()
SaveNewTicket.js:function stateChangedh()
SaveNewTicket.js:function stateChangedi()
SaveNewTicket.js:function stateChangedj()
viewTicket.js:function stateChangeddd()
viewTicket.js:function stateChangedee()

"The only difference between any of the functions was that the xmlHttp variable had a similar 'add a letter' naming convention: xmlHttpa, xmlHttpb, etc. As with the function names, when he ran out of letters, he added a second. aa, ab, etc. And just for fun, the letters in the variable name very rarely matched the letters in the function name, so the function stateChangeda() used the variable xmlHttpop

"I told management that there was nothing worth saving, and we have yet to switch from email and post-it notes.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!