On Open Source License Agreements

While I’m a fan of all the open-source code available on the Internet these days, I sure wish they paid more attention to the licensing agreements to which they require us to agree when we use their code. They’re just confusing. Most just go along with them, but it bothers me enough that I try to avoid them at every turn. Here are some examples with my comments interspersed.

BSD 2-Clause License

Copyright (c) <YEAR>, <OWNER>
All rights reserved.

The parenthesized “c” is not a legal substitute for ©. Fortunately it is not required at all when the word “Copyright” appears. (One of “Copyright”, “Copr”, or © is required in a copyright statement.) The statement “All rights reserved” is redundant and is also not required. These are minor points; they just demonstrate the lack of sophistication of the open source community and those who advise them.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Note that software authors like us who incorporate open-source software into our programs are required to explicitly tell you about the above conditions under the second of those conditions. However, since we don’t distribute the source code, the first condition is irrelevant to you. And since you can’t extract the binary version of the code from our program (it is inextricably compiled and linked into our program in a way that makes it impossible for the end-user to even find, let alone extract), the second condition will never apply to you. Despite these facts, we’re required to tell you the conditions under which you can redistribute this thing that you don’t have, can’t find, and would have no reason to redistribute.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

There are two problems with the above clause. One is that it is unenforceable because you have no way to consent to it. If you are maimed by our program while it is running a line of licensed open-source code, your lawyer would sue the pants off both us and the copyright holder of the open-source code. You would lose, but not because of this clause. It would be because it would be impossible to show that the particular lines of code licensed under this agreement were responsible for your loss of a limb or whatever.

The problem with the BSD licenses is that they really don’t account for 99% of the usage of software components — that is, when they are compiled into another program. It should be sufficient for us to say the following: Portions Copyright <YEAR>, <OWNER>. The owner still gets their attribution and there’s no confusing legalese to confuse an end-user.

MIT License

Here’s another example.

Copyright (c) <year> <copyright holders>

Again, the parenthesized “c” has no legal standing.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

This paragraph defines “the Software” as the files “obtained”. It gives us a list of allowed uses. The construction of the sentence is confusing. If we simplify it by removing what I would call “parenthetical” clauses, we get: “Permission is granted… to deal in the Software without restriction… and to permit persons to whom the Software is furnished to do so, subject to the following conditions”. The question is: Do we have permission to deal in the Software without restriction, or are we subject to the restrictions listed in the paragraph that follows (“subject to the following conditions”)?

One could interpret the paragraph to mean that the person obtaining the software can do two things: First, deal in the Software without restriction, and second, permit other people to do the same but only if the conditions that follow are met. That would mean that a company like ours, which is not distributing the Software (i.e. the files we obtained) is not obligated to meet the conditions of the next paragraph.

One could also interpret the paragraph to mean that the person obtaining the software must always meet the following conditions whether they’re “dealing in the Software” or “permitting other persons to do so”. I think this is the meaning intended by the authors of this license agreement, since users of this form of license seem to believe their copyright notice must be included in any program that makes use of their Software.

The problem, however, with the second interpretation is that it imposes restrictions on those who would “deal in the Software”, and the first part of the statement makes it clear that those who “deal in the  Software” can do so without charge and without restriction.

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

Remember “the Software” is the files “obtained” by the user of the software. We do not distribute copies of those files, and therefore, we do not distribute the Software. So if we interpret the preceding paragraph as saying those who “deal in the Software” are subject to the conditions here (that is, the requirement to include the copyright notice and the permission notice in all copies of the Software), then since we’re not distributing the Software, we’re not obligated to include the copyright statement anywhere in our program (other than leaving it in the original source code, but that is irrelevant to the end user who uses our program).

This paragraph further begs the question, “What is the ‘permission notice’?” The preceding paragraph identifies itself right away as granting permission, so it could be argued that it is the “permission notice”. That leaves the next paragraph in limbo:

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

I would argue that this paragraph, which I would call a “disclaimer”, not “permission”, is for my benefit only and that the preceding paragraphs do not obligate me to pass it along to anyone to whom I might distribute the Software. I’m confident that no open source software author who uses this license agreement does so believing that this disclaimer would not be provided to subsequent recipients of the Software.

I am not a lawyer, but I believe as an expert in computer software and the English language that there is nothing in this license agreement that affects me in any way other than giving me permission to use the product of this open source software author’s work with no attribution, at no charge, and with no restrictions.

Implementing Interprocess Locking with SQL Server

I suppose everyone does this and I just haven’t heard about it. I don’t get out much, so it seems cool to me.

When we redesigned our company website (www.laridian.com) a couple years back, I needed a way to automatically update best-seller lists, new releases, and other dynamic data on the site without relying on an employee to do it every week/month/quarter. Initially, I considered writing a script that did this kind of thing and was launched by the OS on a schedule every so often, but I try to stay away from creating yet another little thing I’ll have to remember if we ever move the site or are forced to recreate it on another server.

So it occurred to me that I could keep track of when the last time was I had created a particular list or other piece of dynamic content on the site, and the first user who requests it after some time period (say once a month for “best sellers” and once a week for “new releases”) would cause the site to notice the content was old and regenerate it. That’s a cool idea on its own, but isn’t the subject of this article.

One of the problems I wanted to avoid was having two or three users who happened to show up at about the same time all trigger the process. I was concerned that it might be time-intensive and while I don’t mind delaying one customer while the data is created, I didn’t want to delay everyone who visits the site during those few seconds. So I came up with the idea of using SQL Server to implement a generic “lock” or “semaphore” capability I could use anywhere on the site.

The idea is to have a simple table with a Name field and a SetTime field. The Name field is given the UNIQUE constraint, so that duplicate records with the same Name field are not allowed. The first customer session that discovers it needs to rebuild the best-sellers list tries to INSERT a record with Name = ‘Best Sellers’ and SetTime = GETDATE(). If the INSERT succeeds, the process “owns the lock” and can do what it needs to do. If someone else comes along shortly thereafter and discovers it, too, needs to update the best-sellers list, it will try to do the same INSERT and will fail due to the existence of a record with the same Name field. This second process does not own the lock, and cannot update the best-sellers list. Instead, it uses the old list.

Once the first session has updated the list, it simply DELETEs the record, thus releasing its lock on the best-sellers list.

Since INSERT is an atomic operation there’s no possibility that two sessions are going to both believe they wrote the record.

Since the web is a flaky place, it’s necessary to allow for the possibility that a lock obtained a long time ago was never released. So every request for a lock checks the SetTime field. If the existing record is “too old” it is deleted before the attempt is made to INSERT the record.

This allows a certain amount of interprocess cooperation and communication between my Classic ASP pages with very little effort.

One of the side-effects is that the locks span not only all the processes running on the server, but can be made to span processes running on user devices. A recent use case that surfaced for this capability was the necessity of keeping a user from synchronizing his notes, highlights, or bookmarks from two (or more devices) with the Laridian “cloud” at the same time. The results can be unexpected loss of data on one or both of the devices.

The solution to this potential problem was for the synchronization process to request a lock that contains both the name of the table being synchronized and the customer ID. That way, many customers can synchronize, say, Bible bookmarks at the same time, but any one user can only synchronize one device at a time. This is a little more complicated than it seems, since PocketBible for Windows and PocketBible for iOS each have their own synchronization script on the server, while our newer clients (PocketBible for Android, Windows RT, and Windows Phone) use our new TCP-based synchronization server. The scripts for the older clients are written in Classic ASP and are invoked through HTTP POST operations from the client, while the new TCP server is written in C# and runs as a Windows Service. All have access to the same SQL Server database, and all implement the same locking strategy, which is working well.

In addition, during the debug process the TCP server runs on my local machine and connects via VPN to SQL Server. I can use and test the locking mechanism in this way before it goes live.

The combination of a very simple implementation using technology (SQL Server) that is well-known and well-tested, and the ability to implement locking across platforms makes this an interesting and (I would argue) elegant solution to a large number of problems.

QuickVerse/Parsons Technology History

I wrote this article back in 2002 to tell the history of my writing of QuickVerse and my time at Parsons Technology. I always intended to keep it up-to-date but never got beyond what you see here. Some people read this and accuse me of living in the past. Those people can go sit on a nail. This is here because people ask me about it. And because it’s kind of interesting especially now that Bob Parsons and GoDaddy have become more widely known.

In the Beginning…
After graduating from the University of Iowa in 1981, I went to work for Rockwell International working on test equipment software for Air Force avionics projects. In 1986 I got involved in a custom programming project with two of my coworkers. We wrote an image processing application that analyzed particle shapes from pictures taken from scanning electron microscopes. It was quite cool. That project allowed me to buy my first PC-compatible, a Compaq Portable II (8MHz 80286, 640K RAM, 20MB HD). A screamer.

My prior computer was an Atari 400 which I modified significantly to make it useful for development work. The average Atari 400 had 16KB RAM and a “chiclet” keyboard. Mine had 52KB RAM and a real keyboard. Plus a 140KB floppy disk to replace the normal Atari cassette tape storage device. I wrote a home budget program in BASIC that, in my opinion, was tons better than anything currently available from Intuit or Microsoft. (It had two critical features: fund-based accounting and deposit templates.)

MoneyCounts and Trash Collectors
When I got the Compaq, I started re-writing my budget program in MS-BASIC. While discussing this with my friend Howard at Rockwell he said, “You really ought to try this MoneyCounts program the guy across the street from me wrote. I think it’s shareware.”

Turns out that Bob Parsons was the guy who lived across the street from Howard. MoneyCounts wasn’t shareware, but sold for only $12. I gave “Parsons Technology” a call and followed Howard home from work that night to pick up my first copy of MoneyCounts 3.0. Martha Parsons met me at the door and said something about “the programmers taking off early” that day. (I later figured out that Bob was the only programmer and he just wasn’t home from work yet.) She handed me a copy of MoneyCounts for $12, and didn’t bother me for sales tax.

With that transaction I became Parsons customer number 6553. A four-digit customer number of which I’m quite proud. (When I joined Parsons a year later I watched Bob write the code that would allow the customer database to accomodate six-digit account numbers.)

Over the next year, Howard and I followed the growth of Parsons Technology. From time to time Howard would say, “Well, Bob got a new laser printer” or “Bob got another computer yesterday.” For a while I thought Howard and Bob must be close friends. After asking a few questions I figured out that Howard was just checking out Bob’s garbage at the curb as he left for work!

When Howard got home from work the UPS truck would be backed up at Bob’s driveway loading up hundreds of copies of MoneyCounts.

In the Fall of 1987 we heard a rumor that Bob was leaving his day job and going full time into the software business.

I Meet Bob Parsons
Sometime in October of 1987 I gave Bob a call. I told him I was a little fed up with Rockwell and was looking for new opportunities. I had learned Pascal (Bob’s language of choice) in college, where I earned a 3.9/4.0 GPA, and I’d had a semester of accounting (more than any human should be subjected to). I figured I was a good match for any programming job he might want to throw at me.

Bob and I met one evening to go over my resume. We talked about lots of topics. I don’t think Bob had spent a lot of time talking to any “professional” programmers. He seemed somewhat embarrassed about his amateur coding efforts. I thought his results were extraordinary, and I told him so.

We met in Bob’s basement / office / warehouse. During the course of the evening the phone rang several times. Bob would pick up the phone and take an order for MoneyCounts, then we’d continue our conversation. At one of these interruptions, Bob picked up the phone, answering “Parsons Technology.” Then after a pause, “One moment please.”

Bob punched “hold” and sat their looking at me. He had a twinkle in his eye like he had just told me a joke and was waiting for me to get the punch-line. I smiled, wondering what he was up to. I could hardly contain my laughter when he hit another button on the phone, taking his caller off hold, and said, “Technical Support, may I help you?”

Low Cost, High Performance Software
Bob and I discussed his business model in depth. He had been impressed with Borland’s recent introduction of Turbo Pascal. At a time when other companies were charging $500 or more for programming language tools, Borland introduced Turbo Pascal at $49. By pricing the product so low, it became an impules buy for anyone connected in any way with personal computing. Whereas one might have thought that you could only sell a Pascal compiler to a programmer, all of a sudden it was like everyone was a programmer! Everybody with a computer had to have a copy of Turbo Pascal. Borland had stumbled onto a pricing model that (as much as we take it for granted today) was revolutionary at the time: Produce high quality software and sell tons of it at a low price.

Bob started out trying to sell MoneyCounts for well over $100. He sold a few copies, but still lost $15,000 in his first year of operation and $25,000 in his second. The third year he upgraded the program and, taking a clue from Borland, dropped the price to $12 — well under the $49 to $99 being charged by his competitors. That year he grossed over $100,000.

As we talked, Bob’s philosophy became clear: Produce high quality software and sell it in volume – direct to the consumer – at an impulse-buy price. To ensure no obstacles to closing the sale, he’d spend the extra money it took to create top-quality, four-color, full-page ads to run in national computer magazines. Furthermore, the ads prominently featured a no-questions-asked, 30-day, money-back guarantee and a toll-free number for placing the order. (Parsons’ toll-free order number still contains Bob’s street address from those days.)

As a direct-to-consumer company advertising primarily through computer magazines, Parsons Technology appeared to the public to be a substantial, dependable company with high quality products. Nobody would have guessed from those early ads that the whole thing worked out of Bob’s basement – with hundreds of packages being shipped each afternoon from his garage… and Howard eyeing his garbage for signs of new toys.

Some Men Drink; I Write Code
Bob left me that night with the comment “I just hired the best programmer I can afford: Myself.” Having left full-time employment, Bob was stepping out on his own and offered little or no security for a young programmer with a growing family. It was pretty clear that if I expected to get a paycheck every week, Parsons Technology was not a good place for me.

I returned home, still reeling with the excitement of the conversation with Bob. He was so excited about what he was doing it was hard to just go to work at Rockwell the next morning for another day of the status quo.

I was growing increasingly depressed working at Rockwell. Working for a giant corporation has a way of sucking all the motivation out of a person. It’s too easy to “coast” and not get noticed. The work was interesting and challenging, but I could see it wasn’t going anywhere.

In the meantime I had finished the image processing application, and was looking for another programming project to fill my free time at home.

While browsing a catalog from Public Brand Software (one of the many shareware distribution companies that sprang to life during the mid-1980’s) I saw two items that caught my attention. One was a program containing the KJV New Testament, and the other was a set of eight disks containing the entire KJV text. I ordered both.

The KJV NT program was OK, but nothing to get too excited about. Searches were kind of slow. It was written by a guy who was a member of an end-of-the-world, gun-hoarding cult. A portion of the registration fee went to the organization, so needless to say I never registered my copy.

The real gem was having the entire text of the KJV Bible available on my computer. At the time, you could pay $50 to $100 for a set of disks like this that was just the Bible in sixty-six text files with a simple “grep”-type program that scanned the text for words and phrases. After trying to search for verses using my word processor for a couple days, I decided I could write a simple program that would make it a whole lot easier to search the Bible than loading it into a word processor.

QuickVerse is Born
My idea was to do some simple compression and indexing. First, I’d scan the whole Bible and make a list of all the different words I saw. After alphabetizing the list, I could assign a number to every word corresponding to its position in the alphabetic list. Then, making another pass through the Bible, I could replace each word with its number. I found there were about 12,783 words in my edition of the KJV.

Since, on average, a word takes about five or six bytes and any number up to 32767 can be stored in only two bytes, I instantly reduced the size of the Bible by about 60% by replacing words with numbers. Plus, since each word takes less space on the disk, I could read more words in less time – thus increasing the speed of access.

The next step was to be able to quickly find every occurrence of every word. I had recently used a really cool (at the time I thought so, anyway) storage technique which allowed me to store two values in one memory location. As long as you know one of the two numbers, you can easily extract the second. The idea is this: You have two numbers, A and B. You want to calculate a value, C, that embodies both numbers. Represented in binary, these numbers occupy 16 “bits” each, where each bit has a value of 1 or 0. Going from left to right (or right to left, it doesn’t matter) compare each of the corresponding bits of A and B. If both bits are 0 or both are 1, the corresponding bit in C is set to zero. If the bits from A and B have different values (0 and 1 or 1 and 0), set the bit in C to 1. The mathematical formula is C = A XOR B.

Now, given A, the value of B can be determined in the same was as C was calculated. That is, B = A XOR C. Similarly, given B, A can be found (A = B XOR C).

I numbered all the verses in the KJV (Genesis 1:1 was 1 and Revelation 22:21 was 31,102). For each word I stored the verse number of the first occurrence of the word in a word list along with the spelling of the word. Then, immediately after the first occurrence of that word in each verse in which the word occurs, I stored both the verse number for the next occurrence of the word and the verse number for the previous occurrence in one, two-byte, location on the disk. Given that you always know where you came from (either from the previous or the next occurrence), you could apply the XOR formula and find the next (or previous) place to go.

So on the whole, it took me four bytes to store a word. About 20% less than the size of the straight ASCII text of the Bible. Plus while I was saving storage space I was adding another piece of information: The location of the adjacent occurrences of the word.

It Sounded Good on Paper!
The beauty of this approach was that for any word, I could take you instantly to the first place that word occurs in the Bible. If you wanted to see the next occurrence, I could also get there instantly. The only problem was that if you wanted to see every place a word occurred in the Bible, I had to walk through the whole Bible finding each occurrence! While this was slow, it was still faster than a lot of other programs available at the time.

Where this approach really broke down was in phrase searches. With a phrase search, you have to find all the verses where all the words in the phrase occur together, then verify that the words occur exactly in the sequence in the phrase. With my approach I had to pick the word that occurred the fewest number of times and look at each verse that word was in for an occurrence of the phrase. For phrases like “John the Baptist” that works fine, because neither John nor Baptist occur very many times.

“Day of the Lord,” however, is a different story.

QuickVerse Takes Over My Life
I started falling into a habit of coming home from work, having dinner and waiting for everyone to go to bed, then programming until three or four in the morning. Start time at Rockwell was 7:30, so I wasn’t getting much sleep. I remember noticing at one point that on many days I was putting in eight hours at Rockwell, then working ten hours at home!

I also found that I was really enjoying working on my Bible program and really dreading going into work. In my performance review in January 1988, my boss pointed out that my night-time programming (at that time on the shape analysis program) was affecting the quality of my work. Not to mention the fact that I had met a couple of guys at work who were equally under-challenged by their work. We tended to take some pretty long breaks.

I applied for some different positions within Rockwell. At the time I was writing code in C and Ada (what a combination!). I applied for a position maintaining the system software that compiled our Ada programs, but the job went to someone less qualified but better “connected.” (She was also a little cuter than me.)

Meanwhile Bob’s comments from our conversation in the fall of 1987 were bouncing around in my head. I began to think, “Is there anyway that I could do with Bible software what Bob has done with financial management software?”

A Hole in the Market
As I looked for other Bible software all I saw were very high-priced, under-marketed products. GodSpeed was fast but incapable. $100 got you a copy of the KJV, and another $150 would buy Strongs numbers to go with the KJV. The program didn’t do much at all. It found words and phrases very quickly, but it was virtually impossible to print or save the results. The company had contracted with a fast-talking salesman who took over production of the product and eventually drove it into the ground – refusing to pay royalties to publishers or split revenues with the owners of the program because “God told him not to.”

WordSearch was idiosyncratic but fairly powerful at $179 for the KJV or NIV. WordSearch had a history similar to the beginnings of QuickVerse, being developed by Dr. Jim Sneeringer out of his home while he worked another job. Sneeringer faced the same problems I would face – that of effectively marketing the program. He would later market the program through NavPress, then buy the software portion of the company back from NavPress and run it fairly effectively on his own.

CompuBible had a well-engineered product with features that rivaled some of its competitors for several years. It was owned by a father and son team out of Texas who had contracted with a long-haired, hippy-type programmer to write the code, and a conservative Bible publisher to market the resulting product. However, at $249 it was just too expensive for most people and the Bible publisher just didn’t know how to effectively market it.

Bible Research Systems offered perhaps the most comprehensive product, but at $299 for a basic package and extra charges to add the most simple add-ons, people weren’t flocking to their door. Their marketing wasn’t bad; advertising in several of the major computer magazines with an ad showing a “ribbon cable” coming out of a Bible – an image they continue to use to this day.

It seemed obvious to me that there was an opening for a Bible software product under $100. My plan was to follow Bob’s model and try to make up in volume what I lost on per-unit margin. Furthermore, I’d spend some money and create some good-looking ads that would convey the idea that “Creative Computer Systems” was more than just my spare bedroom. (I hijacked the company name from the partnership that we had formed to do the image processing system. This made taxes simpler. By this time my partners and I were done with the image processing system and the partnership was just holding together until the end of 1988 when we’d do our final tax return and shut it down. Since I already had the letterhead and the bank account, I thought I’d just market my Bible software under that name.)

My Wife, the Software Sales Rep
QuickVerse began to come together fairly well in the Spring of 1988. I had formulated a plan to begin advertising in the September issue of Pulpit Helps magazine, which came out in late August. That meant I had to have camera-ready art by the first of July and pay the $400 for the ad shortly thereafter. By August 1, I’d have to decide if I wanted to run the ad in the October issue, long before the first ad had appeared. And of course I’d owe another $400. Within a week after the first ad actually appeared, I’d have to decide if I wanted to be in the November issue. It was pretty clear that I’d have to commit the money without knowing how sales were going to go. And I had to have the program done by September.

The summer went pretty fast. I was coding all night and “working” at Rockwell all day. My wife was wonderful about the whole thing. She could see that I was not happy with Rockwell and was deriving most of my job satisfaction from the work I was doing after-hours. We had an agreement that I could work late three or four nights a week, as long as she knew my schedule in advance and as long as we could set aside one night a week plus Saturday for family activities. This was a philosophy I would stick with through the years when work began to interfere with family; I always let her know ahead of time what my schedule was going to be, and I always set aside time as needed, without complaining. I think that did much to keep us both sane during those hectic days.

Late in the summer I went out and spent what little I could afford to have a little two-by-two inch ad done at a local graphic arts shop. I couldn’t afford a four-color ad, but I applied Bob’s philosophy of trying to look like a more substantial company than I really was. I lined up an 800-number that rang into our kitchen. I put a bulletin board up by the phone with a clipboard of order forms, a UPS map depicting delivery times to anywhere in the country, and a price list so my wife could take orders.

Sometime early in September I finished version 1.0 and we waited for the phone to ring. It seemed like an eternity, but finally the first orders came in. I couldn’t accept credit cards, so I sent the packages out on invoice. Getting that first check for $60 was a real kick!

My wife would answer the phone and take orders. Callers wanting technical support were told we’d call them back after 5PM. I paid my 5-year old twenty-five cents per set of disks to duplicate disks for me. I still remember her standing on my office chair, shoving disks into the drive and pressing “Enter” to copy the files from my massive 60MB hard drive to the 5.25″ low-density floppies.

I remember a conversation with my wife in which I commented, “Wouldn’t it be cool if we could make just enough doing this that I could leave Rockwell and do this full time?” I would have been shocked to know that within seven years QuickVerse would support 70-80 full-time-equivalent Parsons employees in various capacities.

“Hello, Bob?”
In October 1988, with things now going fairly well, I had an idea. If I could get a list of churches that owned computers I could do some direct mail and hopefully sell some programs. I started by calling churches in Cedar Rapids and asking if they had time to complete a survey. This gave me an opportunity to find out how big the church was, if they owned a computer, and if the pastor used the computer – among other things. If they sounded like a good prospect I’d send them a letter and offer them a discount on the program. But that was a pretty small list of names and it was very labor-intensive. I needed a better source of names.

I decided it ought to be fairly straightforward to go through Parsons Technology’s customer list and pull out anything that looked like a church. By then they had less than 100,000 customers, but many were churches who were using MoneyCounts (like my church did). I called Bob, who by now had moved out of his house into an office building and somehow had managed to create several layers of secretaries to insulate him from people like me trying to leach onto his success. Bob invited me to visit the office and bring my program along. He asked that I also bring any documentation I had. That seemed weird, but not a problem. I fired up the dot matrix printer and printed off the 25-page QuickVerse user’s guide.

I showed up at Bob’s office at the appointed hour. Parsons Technology occupied a couple thousand square feet in a two-story office building. The front of the office housed about ten order-takers. A small room in the back contained a disk duplicator machine, which clanked out a couple copies of MoneyCounts every minute. A young lady sat on the floor surrounded by invoices and credit card slips.

The programmers occupied a small room in the back. There were two of them, answering Tech Support calls and squeezing in some programming between calls. All told it looked like about 20 people scurrying about.

Bob greeted me and took me to his office. We were joined by someone named Claudia who grabbed my “documentation” and ran off, probably to make an illegal copy. Boy, were these guys cheap!

We installed the program on Bob’s machine and he looked up a few verses. Having been in the corporate leasing business, he did a word search for “leasing.” We all chuckled to see Psalm 5:6:

Thou shalt destroy them that speak leasing: the LORD will abhor the bloody and deceitful man.

The more Bob played with the program, the more he got excited about it. He asked me what my intentions were and I told him my idea of scanning his customer list for anything that looked like a church. He asked me about the competition for the product and what I was selling it for. He seemed intrigued by the fact that all the other Bible software products available at that time were significantly higher than my $60 price. He asked how they were being marketed. I asked for a copy of PC Magazine and showed him the Bible Research Systems ad. It seems like WordSearch might have also been in there. (Both companies had ads in the “business card” section in the back of the magazine where a small 1″ x 2″ ad could be had for a few hundred dollars. The BRS ad featured, of course, the flying Bible with the ribbon cable.)

About then Claudia stepped back in. “How’s it look?” Bob asked. “Looks fine,” she replied. Bob explained that Claudia was his technical writer and director of public relations (I later found out that about everyone wore multiple hats — programmer/tech support, accounting/tech support/human resources, manufacturing/shipping/credit card processing, etc. Bob even once said that his best critic of new ideas was the kid who came in at night to clean the building.)

Bob and Claudia exchanged a few comments that were thinly-disguised efforts to evaluate the marketability of my program without me really catching on to what they were talking about. Finally Bob dismissed Claudia and turned to me. “What would you think of letting us market this product for you? We’d take the product pretty much as-is — we’d write the manual, manufacture the product, sell it, support it, and pay you a royalty.”

This caught me off guard. I wasn’t expecting anything like this at all. I had to quickly search my thoughts and feelings in order to put together some reasonable questions.

“Why would you be interested in Bible software?” I asked.

“Churches represent the largest group of small businesses in the country.” Where he came up with that statistic (an accurate one, no less) was beyond me. “If we can reach churches with Bible software, perhaps we can sell them a copy of MoneyCounts.”

How much input would I have in the marketing and direction of the product? What were the financial terms? The more I questioned, the more I realized that I wasn’t excited about just letting the product go. On the other hand, this looked like an opportunity of another kind, so I threw another twist into the conversation.

Escape from Rockwell
“Would you consider hiring me to continue development on the product and to direct the marketing? This is, after all, a very specialized niche. You’re going to need someone who knows the nuances of the various denominations and sects that make up the audience for this product.”

Now it was Bob’s turn to sit back and think. He didn’t pause for very long before he said, “We’d be willing to consider that. What did you have in mind?” I’d later learn by observing Bob’s negotiating skills that he was putting the ball in my court to make the initial offer in order to gain position in our subsequent discussions — one of many negotiating tips I’d learn from him over the next six years.

I was ready to leave Rockwell, but I wasn’t ready to give up the job security that working for a major corporation affords. I figured I’d be willing to give up a little security for a major increase in income, so I threw out a number that was about 25% higher than my current position, plus a percentage of the sales of my product. I must have been well under Bob’s strike price, because that seemed to light him up. He ended up countering with even more generous terms.

I told him I’d have to discuss it with my wife. Bob suggested I give him a call the next day to let him know what I decided. I reminded him that as it was Friday, the next day would be a weekend and I assumed the office would be closed. “I’ll be here. Give me a call tomorrow.”

Needless to say, my wife and I had a long talk that night. We recalled our conversation in which I had wondered if we’d ever get to the point where I could support myself from sales of QuickVerse. We talked about the security of working for a multi-billion dollar defense contractor versus working for some CPA with a copy of Turbo Pascal. We prayed for God to lead us into the right decision.

I’m Outta Here!
The decision finally came down to one thing: I could sit at Rockwell and wonder what life might have been like to have struck out with Bob, or I could take the challenge and see what I could do to change the face of computerized Bible study. In that light, there was no decision to make. I drafted a letter of resignation.

Monday morning I set up an appointment with my boss for right after lunch. Over the noon hour I drove over to Parsons Technology (which, coincidentally, was located right across the street), and Bob and I hammered out an employment agreement. With that in hand, I knew it was safe to go back and submit my resignation.

At 1:00 I went to see Neil Ennis, my supervisor. I brought along a copy of my ad from Pulpit Helps magazine and a brochure I’d had printed up. I told him how I’d been working nights to write this Bible software, and that’s why my heart had not been in my work. I told him the story of taking the program to Bob for the purpose of renting a mailing list, and how Bob had offered to hire me. Neil of course knew that I’d been applying for various positions within Rockwell, and suspected that I wasn’t challenged any longer by the work we were doing.

In what was to become a trend of bucking the system, I gave Rockwell only one week’s notice – I planned to start at Parsons the following Monday (technically, 6.5 days later). Neil wasn’t sure if Human Resources could process the paperwork that fast. I told him it didn’t really matter to me, I could come back a week later and sign some papers if that what they wanted, but I was definitely going to be at Parsons Technology on Monday.

Ironically, the manager who had hired the cuter programmer a few months before called me later that week and said, “I heard you’re leaving the company. Is there anything we can do to get you to stay? Maybe we could open something up for you.” I threw out a salary figure that was about twice what Parsons would be paying me. “If we can talk about numbers like that, I’ll give Rockwell a second chance,” I said. Needless to say, they weren’t interested. Idiots. They should have jumped on me when they had the chance.

A Rose by any Other Name?
One of the first orders of business upon arriving at Parsons was to name the program. The name I’d been using for the program was not one that Bob thought was very good, so we started working on ideas. At the time, search speed was about the only criteria that was used to compare Bible software. We wanted to convey the idea that the program was fast. Part of the name had to be something like “Fast” or “Quick.” This got me thinking about the verse that says that the word of God is “quick and powerful; sharper than any two-edged sword.” I sketched out a thumbnail of an ad with the name “Sword’s Edge” with the headline “Quick and Powerful.” I thought it was a pretty cool name.

Bob wasn’t as impressed. He thought it sounded to “churchy.” He wanted something cleaner; something that would extend the reach of the product beyond the well-churched crowd. I brought him a list of dozens of more names constructed from words implying speed combined with words related to the Bible (“word,” “verse,” “Bible”). I don’t recall that he liked any of them.

After I got home it really burned me that he hadn’t liked “Sword’s Edge.” I called him at home and we had a long heart-to-heart about how much of a role I was going to have in the company. It seemed like I should be able to pick the name. Bob assured me that he wanted me to be happy with it, but that he’d like to come up with something that we’d both be happy with. He managed to calm me down, and in the course of the conversation I threw out two or three of the best new names from the list. “QuickVerse” caught our attention.

After sleeping on it, QuickVerse was chosen as the name for the product. In retrospect, Sword’s Edge was even dumber than the original name of the program…

“Logos.”

A New Product is Born
Bob had a few suggestions to make the program better. He wanted enhanced printer support, so I wrote a reconfigurable printer driver. These were the DOS days, remember? Everybody had to memorize the binary code that turned an Epson printer into condensed mode. QuickVerse would remember those codes so you wouldn’t have to.

I worked on updates to the program through Christmas. In the meantime we wrote the manual and prepared the initial ads. “Instant Bible Access – Only $49” was the headline. A picture of about a dozen floppies scattered around a big Bible led the reader into copy that boasted of QuickVerse’s fast access to the entire text of the Bible and wildcard searches. (One customer returned the product because he didn’t get “the big book in the ad.” Another, upon seeing a different ad with a picture of QuickVerse running on a computer, bought QuickVerse thinking he was going to get the computer too. Once he figured out his mistake he called to say “I bought your program, but I don’t have a computer to run it on. What do I need to buy?”)

A friend of mine wrote the manual. It featured a summary at the beginning of each chapter that let experienced users get everything in about a paragraph that we were going to spend the next ten pages explaining. I think it was one of the best manuals we ever did. But then the program was so simple the manual really wasn’t even necessary.

QuickVerse was the first Parsons product to have enough disks that it needed a box. Previously, copies of MoneyCounts sold through software stores had just been two disks shoved inside a manual, then shrink-wrapped by Bob’s twelve-year-old daughter. QuickVerse had a smaller manual and about five times as many disks. The box featured a stylized dove. While it was a little more “charismatic” than I would have normally gone for, it did have a unique look.

QuickVerse was also the first Parsons product that really taxed the capacity of the little disk duplicator sitting in the shipping room. I went shopping for a system that could duplicate disks at about 150 disks per hour. It was driven by a PC. We quickly outgrew that system and within about three months had upgraded to a Unix-based system with three duplicators, bringing our capacity up to 450 disks per hour and giving us the option of duplicating 3.5″ disks. (Parsons currently operates about 36 such duplicators with a capacity of about 9000 disks per hour. During our tax season we run three shifts, for a total capacity of over 200,000 disks per day. Even at that rate we have to send a large number of disks to outside duplication houses.)

Bob told me once that we’d eventually sell 100 copies of QuickVerse per day. I would’ve been happy with 100 per week. QuickVerse started shipping in mid-January, 1989. By the end of January we had sold 973 copies – about 97 per business day. At the end of March, Zondervan told us we held 33% of the total market for electronic editions of the NIV. Three months later we had doubled our per-quarter sales rate. Zondervan released their own electronic product that quarter. Interestingly enough, they refused to give us market share information after that. But based on our calculations, we figured we were outselling all of our competitors combined (including Zondervan’s).

QuickVerse for the Macintosh
Kurt Hansen was the first programmer Bob hired. Kurt worked for the company that installed Bob’s first network. They got to know each other and Bob ended up hiring Kurt.

Kurt made an early attempt in the summer of 1988 to write a Mac version of MoneyCounts. He didn’t get too far before it became obvious that the project was going to be bigger than the company was willing to commit to. This would be the first of several times that Parsons would start and stop Macintosh development.

One of the assumptions I had been hired under was that I would write a Macintosh version of QuickVerse. The first ads said “for PC or Macintosh.” With the word already out that the Mac version existed, we had to hurry to put something together. Bob offered to have Kurt work with me on the Mac project.

Our plan was to have Kurt create a “framework” with all the “Mac stuff” pre-coded, then I would step in and code all the “QuickVerse stuff” (like the decompression and search engine). Kurt started with the code he had developed for MoneyCounts. Because we were in a hurry, many of the data structures and definitions from MoneyCounts were left in. As a result, QuickVerse for the Mac shipped with date calculation code and the definition for a double-entry accounting data structure still in place.

We shipped the Mac version in April 1989. It did fairly well, but never represented more than 10% of our sales. In a way that was good; the Mac software market was about 10% of the total PC software market. But with the shortage of Bible software for the Mac we thought we should have been able to do better than 10%.

But the real problem was Technical Support. We had a small group of techies, all of whom were hired for the knowledge of DOS and PCs. When the Macintosh came along, we figured we’d just show them where the System Folder was at and teach them to hold down the mouse button when they dragged menus down and that would be the end of it. Besides, the Mac was supposed to be so easy to use, who’d need Tech Support?

We had also heard that Mac users knew their machines better than PC users. The reasoning was that the machines were so much easier to use that they naturally learned everything about them. Plus Mac users bought 2-3 times as much software for their machines than the average PC users. It should be no problem to support these guys!

Boy, were we wrong. One of the problems with the Mac being so easy to use was that our techies could say, “Well, you need to add a mouse driver to CONFIG.SYS. Give that a try, then call me back if it doesn’t work.” These confident Mac users, not knowing that Macs don’t have a CONFIG.SYS file but figuring, “Hey, it’s a Macintosh – it should be easy!” would hang up the phone then sit there and stare at their monochromatic screens searching all over the place for the file. (What did that Tech Support guy call it? ‘Can figs date sis?’ Hmmm… must be here somewhere.)

A year or two later we discontinued the Mac version of QuickVerse. It was too hard to maintain multiple development and support teams on the limited income we were receiving from the program.

Those were the days….
That was back in the days when I was still writing code. Sometime between writing the Mac program and getting Membership Plus off the ground I re-coded the whole way that QuickVerse stored its Bible files. Version 1.21 shipped in May 1989 and had a much more efficient concordance structure, including a technology for doing Boolean searches that we don’t think too many other Bible software companies have figured out, even to this day.

“Oh, and by the way, Craig, we need a church management program!”

One of Bob’s marketing plans was to get churches “hooked” by selling them QuickVerse, then turn around and sell them a copy of MoneyCounts, too. The opposite would also work… churches already using MoneyCounts to track their finances would be very likely to be interested in Bible software.

So Bob tasked me with looking at MoneyCounts and coming up with a list of enhancements that we’d need to make it useful for churches. In examining the program I could find only one major flaw: The lack of fund accounting.

Fund accounting is a cash-based accounting system in which balances are maintained in several designated funds. Income and expenses are written against these funds, so that it’s obvious when you’ve overspent your “budget.” If an expense would cause the balance of a fund to go negative, it’s necessary to steal money from another fund to cover the expense. In a way, it enforces a budget: You can only spend what you’ve got.

I spent quite a bit of time explaining fund accounting to Bob and the other accountants at the company. I didn’t make much progress. (I’m not going to go into the topic of helping CPAs understand basic layman’s accounting principles. I’ll save that for another article.) I settled for writing an article for the customer newsletter (the MoneyCounts Ledger) describing how to set up fund accounting using equity accounts in MoneyCounts.

But my research uncovered another shortcoming in MoneyCounts. There was no way to track contributions – an important task for church treasurers who have to provide reports to their contributors for IRS purposes at the end of the year. In the course of designing a program to handle this task, it grew into a full-fledged database management program for churches that included membership tracking, attendance, pledges, label printing, reporting, and more.

Help!
Needless to say, I needed help. In January 1989 while coding the Mac version of QuickVerse I interviewed and hired Steve Spencer, a recent Computer Science graduate from Bob Jones University in Greenville, SC. Steve was a native of Rockford, IL, so I knew he’d be no stranger to Iowa winters (a significant job hazard for programmers relocating from Southern California). Steve was an expert Pascal programmer. I brought him onboard to work on the program that would become known as Membership Plus.

Simultaneously, work was piling up on QuickVerse. We wanted to do version 2.0 by Christmas 1989. Version 2.0 would be a full “terminate and stay resident” version of the program which would permit the user to use his word processor and QuickVerse at the same time. I was working on both the PC and Mac versions. Kurt and I wrapped up the Mac version in April and I put him to work with Steve on Membership Plus. I felt Kurt’s Pascal expertise and the fact that he had some more programming experience would help Steve wrap up Membership Plus within six to nine months.

I needed help if we were going to keep all this afloat. Back at Rockwell I had worked with an electrical engineer by the name of Jeff Wheeler. I was the only “pure software” guy in our 70-engineer group. As a result, I tended to get involved in a lot of tasks. I needed someone to move things on to once they were well established and everything was working well. We hired Jeff to take my programming tasks on a major Defense Department communication system so that I could move on to the Fun Stuff.

Jeff had proven to be a quick study. He was meticulous and thorough. What was most disturbing is that he actually listened to what I told him about programming and did all the things that most programmers talk about but don’t actually do themselves – things like using named constants, meaningful variable names, abundant comments, data abstraction and more. As a result he had turned into quite a gifted programmer.

Over the course of 1989 I had tried to get Jeff hired into every spot that came open. I think I offered him some real jewels; he remembers differently. I remember offering him a shot at being responsible for bringing third party software products into the company and perhaps also director of IS. He recalls me suggesting a janitorial position and something on the assembly line in manufacturing. One of us could be wrong.

Late in the summer of 1989 I convinced Bob to let me open a programmer position in my department and I hired Jeff. Jeff’s job would be to learn all that was learnable about QuickVerse and eventually take my coding responsibilities on that project. Jeff started in August 1989. Our goal was to ship QuickVerse 2.0 by Christmas, but it became obvious that wasn’t going to happen. Instead, Jeff and I dove into researching how to create a stand-alone TSR program we’d later call the QuickVerse Companion. That program shipped around Christmas of 1989.

The Rush to the Mad Summer of 1990
We had felt for a long time that Christian bookstores offered an excellent channel for church and Bible related software. Bob had very little interest in selling software through stores. Our emphasis was on marketing direct to the consumer through magazine ads and direct mail. Computer software was not yet hot at retail, though some larger cities had dedicated software stores. Most people bought direct from manufacturers and magazines like Computer Shopper were read cover to cover by these early adopters of PC technology.

But we had a niche product that was targeted to the same people who shop in Christian bookstores. (Or so we thought. Turns out most people who buy software are men; most who shop in Christian bookstores are women.) As we researched the market we discovered the Christian Booksellers Association (CBA). Most of the better bookstores were CBA members. We were told that the premier event of the year was the CBA International Convention, held each year in July. Our best shot at getting QuickVerse into Christian bookstores was getting space at the CBA convention.

In the Spring of 1989 we had contacted CBA to find out about exhibiting. It turned out space was limited only to members of CBA, and that the convention was full. To get on the waiting list we had to join the organization to the tune of a couple thousand dollars. It seemed like a waste of money to join the organization in order to get on a waiting list and potentially still not be able to exhibit. But it was our only choice. In September 1989 we joined CBA and got on the waiting list for the convention. Early in 1990 we were notified that we had a booth.

Our plan was to announce QuickVerse 2.0 and Membership Plus at the CBA convention in July, then ship the products as soon as we got home. By this time, development on Membership Plus had been going on for a full year, certainly we’d be done by July. QuickVerse was in pretty good shape, though we were trying to negotiate additional Bibles (since QV 2.0 would support displaying up to four Bibles simultaneously!) and implement Strongs Concordance at the same time. While all this was going on, I was busy learning everything that we’d need to know about exhibiting at the convention. We’d need to buy a display of some kind and we hoped to have some kind of evening activity during which we’d demonstrate and launch our new products in a flurry of trumpets, flags and miscellaneous hoopla.

I’m not sure why in the midst of this chaos I thought I needed something else to do, but events were about to conspire against me to turn 1990 into a nightmare.

Enter Bible Illustrator
Early in 1990 I was contacted by Tony Tooley, author of a program called InfoSeek. InfoSeek was a program containing stories, quotes, jokes, and news items that related to or conveyed biblical principles. He had offered the program to NavPress Software, a division of NavPress publishing, but thought it would be a good idea to get another player interested. Tony wanted to distribute the product through one or the other of us in exchange for a royalty on the sales of the program. Initially, there didn’t seem to be much of a contest, as NavPress was offering way more than Parsons would consider. But I think I convinced Tony that we could sell far more copies of the program due to our larger customer base and active direct marketing efforts. I gave him the sweetest deal Bob would let me put together but in the end he took NavPress’s offer.

The exposure to Tony’s program had convinced me there was a need for something like this. I had seen advertisements for books of sermon illustrations and subscription services that offered illustrations on a monthly basis, but nothing in software. I knew the software itself was no big deal — a simple database with some specialized search capabilities and that’s about it. But the secret to success would be in obtaining access to as much content as possible to put into the program.

Coincidentally about that time I received a “card deck” advertising pack (about 100 postcard-sized ads in a cellophane wrapper) containing an ad for Sermons Illustrated, a bi-monthly subscription service offering 60 new sermon illustrations per issue. I contacted Jeff Carroll, the author, and we began discussions of licensing his material for use in a software program.

Pastor Carroll had purchased Sermons Illustrated from another pastor, who had about 15 years worth of illustrative material and a small database of subscribers to the bi-monthly updates. Pastor Carroll was negotiating with Baker to publish the back issues in book form, but those negotiations had not really worked out. In the end we agreed to acquire the back issues (about 2000-3000 illustrations) and contract with Pastor Carroll to distribute his subscription service electronically. He said he’d box up the back issues and send them to us.

It would be impossible to describe my shock upon receiving this material. I had anticipated receiving a couple thousand index cards that I’d have to have someone type or scan in to my program. Instead, we received two large boxes full of what were literally scraps of paper containing handwritten notes, newspaper clippings, and typed illustrations. The task of converting all this into electronic form fell to a couple of the secretaries at Parsons, who began taking this work home to work on after hours.

In the meantime, it was my job to come up with a program to contain all this information. I was on the road a lot at the time, so Bible Illustrator began its life beside a swimming pool (somewhere in North Carolina as I recall). With my laptop in hand I donned shorts and a t-shirt and sat back to begin coding. Ahh, this was the life… not a cloud in the sky, my laptop computer on my lap, iced tea beside me, and… rain! Suddenly from out of nowhere, I was getting soaked! I knew my Toshiba 3100SX was rugged, but in that split second I didn’t have time to think about whether or not they’d tested it under water. I jumped up and ran for cover. Immediately the rain stopped. Only then did I realize that the sprinkler system was the source of the water. Seems they water their plants and guests at the same time here.

Undaunted, I relocated my makeshift programming workstation to another part of the patio and after checking carefully for hidden plumbing systems, went to work. Now I realize that programming is a lot tougher now, what with Windows and all. But back in those days we were expected to implement mouse-driven, windowed applications in a DOS environment. There were no “class libraries” to ease the implementation of fancy user interfaces. If you wanted a drop shadowed window you drew every pixel of the border and the shadow and restored the former screen contents under the window when you were done. Anyway, Bible Illustrator was born late in April and shipped on July 31. Hey, I couldn’t waste all my time on BI, I still had coding responsibilities on QuickVerse!

1990 CBA Convention
There’s a waiting list to get into the CBA convention. Lots of companies are vying for a small number of openings each year. The show is big enough that it only fits at some of the largest venues in the country. New exhibitors are allowed one 10′ x 10′ booth the first year, so we were faced with trying to make a big impression from a very small space. In typical Parsons Technology style, we did this by buying more ad space than we had floor space in the booth.

One of the unique advertising opportunities at this convention was a TV show that was produced on-site each day, then broadcast to all the convention hotels. Each day a different 30-minute show was produced, featuring news from exhibiting companies.

Little did the viewers realize, of course, that the companies featured in the news stories were actually paying for the time. We bought the biggest package we could and got a couple minutes of commercials each day and one news story during the week.

One of the main problems with being a new exhibitor among 450 companies was getting people to find your tiny booth. We played off that with a series of commercials in which a couple of bookstore managers sought to find our booth. We found a couple who owned a bookstore who volunteered to play the part of our frantic buyers. We shot the commercial on the show floor the day before it opened to the public. The harried attendees struggled to find our booth on the huge convention floor, often running into each other heading in opposite directions, until they finally found us. The commercial was great fun and produced a lot of traffic.

To launch our three new programs we planned a 2-hour event after one of the first days of the show. At the event we’d demonstrate each product, and of course there’d be food and drink. We sent invitations to all registered attendees in advance of the show, and received a surprising number of RSVPs. We booked a small ballroom at the Hyatt in Denver and ordered up some cookies, coffee and punch.

As we talked to buyers during the show we mentioned the event and were surprised at how many said they’d come. We handed out hundreds of tickets and began to wonder if we’d planned enough food and space. I got nervous and called the hotel. Yes, the Grand Ballroom was available, and yes, we could get more cookies and punch. I doubled or tripled our order and had the room set up for 700 guests.

About 50 people showed up. Had we thought about it we could have figured it out. The show starts at 9 AM and runs until 6 PM. Most people are on their feet the whole time, going from booth to booth placing orders for products for their stores. Our event started at 7 PM, so there wouldn’t be time for people to eat. We were offering cookies and drinks — hardly a meal — and two hours of boring product announcements.

Somewhere in Denver a homeless shelter received dozens of “monster cookies” the next morning, and each of our staff members took a pile of cookies back to their room. I didn’t want to see another M&M monster cookie for months.


Remember, this article is copied and pasted from an old version of my site. At this point, the old article said “I’ll be back to tell more,” and I used the space below to take some notes on what happened in the years that followed. As you can see I stopped updating the list in 2002. The ownership changes became too frequent and confusing and I couldn’t keep up with them. In the meantime I had started Laridian and my interest in what was going on with QuickVerse was rapidly fading. So here are my notes through 2002…

1990: The rest of the story of Bible Illustrator, Membership Plus, and QuickVerse 2.0. Christian Computing Magazine and conventions.

1991: GreekTools, HebrewTools and the inimitable Larry Twitty

1992: QuickVerse for Windows

1993: PC Bible Atlas, Holman Bible Dictionary (Sometime in 1989 I had the idea to write a Bible geography program which would feature a database of every place in the Bible, with the ability to create maps by selecting places from the database and dropping them onto blank map backgrounds. (Bob will claim that this was his idea. I’ve learned not to question Bob, so if it comes up, I’ll admit that it was his idea.) It wasn’t until August 1993 that the program became a reality with PC Bible Atlas for Windows.)

1994: The ill-fated “QuickVerse” for the Newton MessagePad, QuickVerse 3.0, Membership Plus 2.0, The Geography Division, Intuit

1995: STEP is born, Membership Plus 3.0, HebrewTutor

1996: STEP books, GreekTutor, QuickVerse 4.0, Walk in the Footsteps of Jesus

1997: STEP books, Membership Plus 4.0, Ministry Notebook, Bible Illustrator 2.0, QuickVerse Multimedia Life Application Bible, Broderbund, loss of PTE, RIF.

1998: Membership Plus 5.0, QuickVerse 5.0. Purchase by The Learning Company, PalmBible and Laridian, my departure from Parsons.

1999: PalmBible continued; working from home. Laridian acquires MyBible. TLC bought by Mattel, Mattel sells Church Software Division to Findex.com. Only 3 of 30 original employees remain by the end of the year.

2000: Laridian participates with Microsoft in the launch of Pocket PC with PocketBible; MyBible CD-ROM product introduced to Christian bookstores; Laridian hires its first non-founding employee. Mattel sells what’s left of The Learning Company to Gores Technology; Findex falters on QV7. Findex fires the guy who replaced me (Bill Terrill).

2001: Findex fires its CEO. Laridian acquires PrayerPartner for Palm OS.

2002: Findex re-hires Bill Terrill. Memorize! for Palm OS and Pocket PC. More reference books. PocketBible retail product. Laridian hires former Parsons employees Michelle Stramel and Jim VanDuzer. Four bucks will get you a cup of Starbucks coffee and 100 shares of Findex stock.

Handy SQL Server Snippets

There are a few SQL Server tasks I do infrequently and always forget the syntax. I’m going to start collecting them here.

ALTER TABLE ExistingTable ADD NewColumn INT NOT NULL DEFAULT(0) WITH VALUES

This adds a new column with a default value of 0, and populates existing rows with 0 in the new column.

ALTER TABLE ExistingTable ADD NewColumn INT IDENTITY

This adds a new “auto increment” (identity) column and populates existing rows with values for the new column. The values are somewhat random but start at 1 and increment by 1.

INSERT INTO ExistingTable (Col1, Col2, Col3) SELECT Col1, Something AS Col2, Col3 FROM ExistingTable WHERE Conditions

This statement inserts rows into an existing table based on rows returned from the SELECT. If the SELECT clause specifies every necessary column in the same order as they appear in the CREATE statement that created the table, there’s no need to list them in the INSERT clause. In other words, it’s best to include the column names in the INSERT clause.

Fixing Mac OS X 10.7 “Lion”

Apple has a bad habit of hiring kids who have no concept of what came before them. This article helps you undo some of the changes they inflicted on Mac OS X in their attempt to make it “better”.

Reversing the Scrolling Direction

In 10.7, using the MacBook trackpad or the scroll wheel on your mouse will cause you to scroll in the opposite direction than you did previously. Instead of conceptually moving a view port over the document, you are now moving the document. This change was made to accommodate tablets and touch screens, where it seems more natural to use your finger to drag the document. However, rather than making the change apply only to touch screens, they changed all input devices. The result was that the screen appears to scroll backwards if you use a trackpad or scroll wheel.

To fix this, go to the Trackpad pane in System Preferences and uncheck the box for “When using gestures to scroll or navigate, move content in the direction of finger movement”.

Stop Apps from Reopening Previously Open Documents

One of the principles we use in iOS development is that the program should save its state so that when you re-launch it, it will appear as if you never left it. The reason this is essential on mobile devices is that historically they have managed memory themselves rather than depending on the user to close apps they are done with. Since the user never knows if an app has been removed from memory, it would be disconcerting if sometimes the app returned to a default state and sometimes it picks up where you left off.

With both Apple and Microsoft moving toward using their full desktop operating systems on mobile devices, they have begun to take principles that previously applied to small devices with limited resources and applying them to their desktop operating systems even if that doesn’t make sense. On the desktop, the user is the king of memory management. The user opens and closes documents and programs as his task requires. As a partial step toward the integration of mobile and desktop operating systems, the latest version of Mac OS X does two things: First, it saves the state of every app when the app is removed from memory, then restores it when it is re-launched. Second, it remembers what was running when you rebooted your computer, and resumes those programs when it boots up.

The problems introduced by this are myriad, but we can’t expect the little kids at Apple to know that, since for them new is always better and the past is for dead presidents and dinosaurs. For example, if I’m privately reviewing a spreadsheet containing everyone’s salary, then exit Excel, then the next day an employee brings me a spreadsheet for us to review together, when I open Excel the first thing the employee will see is my spreadsheet containing everyone’s confidential salary information.

Disabling this behavior is difficult but not impossible. First, go to System Preferences, select the General pane, and un-check the box for “Restore windows when quitting and re-opening apps”. You’d think this would be enough, but it’s not.

Next, you need to find the folder where Mac OS X saves application state and delete any existing state information. Otherwise, your programs will always restore whatever state was current when you unchecked the box on the Preferences pane. Unfortunately, this folder, which was visible in previous versions of the OS, has been hidden in 10.7. To make it visible, run the Terminal app (Applications > Utilities > Terminal) and enter the following:

chflags nohidden ~/Library/

Now select your Home folder in Finder and you’ll see Library. Open the Library folder, and scroll down to “Saved Application State”. Open that folder and delete everything it contains.

Just to make sure your apps don’t ignore the system preference and save their state anyway, go back to the Library folder, right-click on Saved Application State, select “Get Info”, and set the Sharing & Permissions for your user name to “Read Only”.

Parcelable

General Description

An object that implements the Parcelable interface can be “flattened” for inter-process communication or, as is the case most of the time when I use it, for placing in a Bundle (which is a Java associative array or dictionary).

The documentation makes this seem a lot harder than it is. The sample code from the documentation pretty much covers it.

Implementation

1. Implement the Parcelable interface

public class MyClass implements Parcelable
    ...
    @Override
    public int describeContents()
        {
        // From what I've read on the Web, this function should always 
        // return this value. The documentation is very, very vague. I 
        // think this value is actually used only when the parcel really 
        // is a file descriptor.

        // return CONTENTS_FILE_DESCRIPTOR;

        // The sample in the documentation for a general object like mine
        // just returns 0 here.

        return 0;
        }

    @Override
    public void writeToParcel(Parcel dest, int flags)
        {
        // Order is important. The order here should be the same as the
        // is expected in the constructor

	// It sometimes comes in handy to write arrays of values. The 
        // syntax looks like this:

        dest.writeIntArray(new int[] {publisherID, bookID, section});
        dest.writeStringArray(new String[] {verseReference, anchor, TOCPath});
        dest.writeBooleanArray(new boolean[] {wasHyperlink, noHistory});
        }

2. Implement the CREATOR field

Again, the documentation is weirdly vague, but here’s what it looks like. Yours can look identical to this with the exception of “MyClass”, which is the name of your class:

    public static final Parcelable.Creator CREATOR = 
        new Parcelable.Creator() 
        {
        public MyClass createFromParcel(Parcel in) 
            {
            // Calls our constructor that takes a Parcel

            return new MyClass(in); 
            }

        public MyClass[] newArray(int size) 
            {
            return new MyClass[size];
            }
        };

3. Implement a constructor that takes a Parcel

The parcel will have been created with your writeToParcel() method, so it should read values back from the parcel in the same order that you wrote them out:

    public MyClass(Parcel in)
        {
        // Since we used some arrays to demonstrate the writeToParcel()
        // method, read them back here in the same order.

        int [] intData = new int[3];
        in.readIntArray(intData);
        publisherID = intData[0];
        bookID = intData[1];
        section = intData[2];

        String [] stringData = new String[3];
        in.readStringArray(stringData);
        verseReference = stringData[0];
        anchor = stringData[1];
        TOCPath = stringData[2];

        boolean [] booleanData = new boolean[2];
        in.readBooleanArray(booleanData);
        wasHyperlink = booleanData[0];
        noHistory = booleanData[1];
        }

Putting a Parcel in a Bundle

I often use Parcelable objects as parameters to an Intent:

    // Create the parameter object

    MyClass param = new MyClass();

    // Load it up

    param.publisherID = 3;
    param.bookID = 4;
    param.verseReference = "John 3:16";
    // etc.

    // Create the intent

    Intent intent = new Intent("com.laridian.pocketbible.DOSOMETHING");

    // Put the flattened parameter in the Intent and broadcast it

    intent.putExtra(getString(R.string.someparam), (Parcelable) param);
    sendBroadcast(intent);

Retrieving a Parcel from a Bundle

Retrieving the flattened object is no different than retrieving any other object from the Bundle. It will be un-parceled by the cast:

    MyClass reconstructedObject =
        (MyClass) intent.getExtras().getParcelable(context.getString(R.string.someparam));

Don’t store Parcels!

Parcels are not meant to be persistent. They are meant to have short lives, since the format could change between releases of the API/SDK/JRE. Don’t store them anywhere.

Externalizable

Introduction

Java supports two techniques for object permanence: Serializable and Externalizable. These two are related but different. Serializable is more automatic and less flexible. Externalizable is less automatic but more flexible. Serializable is rumored to be slower in some implementations than Externalizable. Because Externalizable gives me a lot more flexibility, I choose to use it exclusively.

Making a class Externalizable is relatively easy. It amounts to implementing two methods: One for writing the state of your object and one for reading it. It also requires that you provide a no-parameter constructor so the system can automatically instantiate your object prior to asking you to read its fields from the file.

By default, any change you make to your class (such as adding a field) will cause any previously serialized data to be incompatible with the class. To resolve this, I take over responsibility for all versioning, as detailed below.

Details

1. Implement Externalizable

Your class needs to implement Externalizable, which requires two functions:

    @Override
    public void writeExternal(ObjectOutput output) throws IOException
        {
        // Write the version number to output using writeInt().
        // Write the fields from your object to output.
        }

    @Override
    public void readExternal(
        ObjectInput input) 
        throws IOException, ClassNotFoundException
        {
        // Read and test the version number.
        // Read the fields of this object in the same order that you wrote them.
        }

2. Add a public constructor with no parameters

You need to add a no-parameter constructor to your class if there isn’t one already. It must be declared “public”. When reading your serialized objects, your object will be constructed using this constructor, then readExternal() will be called.

3. Define serialVersionUID

Add the following field to your class. This identifies the class so the serialization code knows what kind of object to instantiate in its readObject() method:

    private static final long serialVersionUID = 91089626578087866L;

The value of this UID is irrelevant, but it should be unique among the other serialized classes in your document. I use random.org to generate a couple random numbers less than or equal to a million, then concatenate them to create a random long. If you omit this step, the compiler will generate a UID for you, but since it’s based on the class signature it will change if you change just about anything in the class. This will cause an exception to be thrown when you try to deserialize a previously created file. So it’s best to define your own.

4. Manage changes to your class fields

Since you’re defining your own serialVersionUID, you need to completely manage version changes in your serialized file. I create another constant for this purpose:

    private static final int serializationVersion = 1;

In writeExternal() this is the first value I write to the file. When reading, I read this value and test it to make sure I understand the version of the file being read, then make decisions based on the version of the file I’m reading. I may have to supply default values for new fields added to the class since the file was written.

If I don’t recognize the version, I throw a new IOException with a description of the problem:

    throw new IOException("Unrecognized archive version");

5. Notes on writeExternal()

In writeExternal(), use writeInt(), writeBoolean(), etc. to write field values. For enums, use writeObject(). For Strings, use writeUTF(). For your own classes, use writeObject(), then implement Externalizable in those classes.

How NOT to Stream Live Video from your iPhone

Today I thought it would be cool to stream video of my run to the Internet. I was sure there was an app out there that would do it, and sure enough there is: UStream.

I installed the app and went through the process to set up an account. At the end of entering my data, it said there was already an account for my email address. That was weird; I had never downloaded this app before. I suppose it’s possible I’ve tried installing this program in the past, so I figured I’d ask it to send my password to me and I’d log in to this mysterious, already-existing account.

When I clicked the “forgot my password” link, it asked for my account ID, not my email address. I entered the most likely account ID I may have used in the past, and it told me there was no account for that ID. So I entered a second account ID I sometimes use and sure enough, it said it was sending password reset instructions to me by email.

I waited and waited for an email but it never arrived. So somewhere out there, the person with the account ID “craigr” got a mysterious email asking him to reset his password.

In the meantime I decided to log in with a different email address and was able to set up a new account. I proceeded to the next step, which was to connect my account to Facebook so it could notify my friends when I was broadcasting live video. I got the familiar “connect to Facebook” dialog and entered my Facebook login credentials. Facebook asked for my permission to share all my personal data with UStream, and I agreed. This led to a screen that said, simply, “Success”. There was one and only one button for me to push. It said “Cancel”. I waited and waited but nothing happened. I finally decided to push the Cancel button, and sure enough, it canceled my login.

After trying a couple more times I decided to do an end-run around this stupid process. I went to my iPad and logged into their website using my newly established account. Going into my settings page on the website, I enabled the option to connect to Facebook. Facebook seemed to remember I had given it permission to interact with UStream, so that all went well.

Returning to the iPhone, I exited the application and re-launched it. I tried connecting to Facebook but with no luck. The program simply doesn’t work.

I still think it would be cool to broadcast live during my run and somehow interact with people. UStream is definitely NOT the way to do it.

How Strong Passwords are LESS Secure

We all know how important it is to use strong passwords and not to re-use passwords on different sites. We’re told not to use real words, not to use the names of pets or family members, not to use our birthdates, anniversaries, or Social Security numbers, and not to use common passwords like “password”, “1234”, and “qwerty”. And yet some of the most popular passwords at many sites continue to be easily remembered names, dates, or words.

Some sites have instituted draconian policies to make sure you use a secure password. Ironically, while some of these are banks, others are discussion forums for hobbyists or the comment section of a news site. I can understand why my bank wants me to use a secure password, but the comment area of The Mooselick Times?

Recently I was setting up a temporary testing account with Apple and had this exchange with their password validator:

Password: test
“Passwords must be at least 6 and no more than 32 characters.”

Password: testing
“Passwords must be at least 8 characters.”

Password: xxxxxxxx
“Passwords must contain at least one digit.”

Password: xxxxxxx1
“Passwords cannot contain more than two consecutive identical characters.”

Password: testing1
“Passwords must contain at least one upper case letter.”

Password: Testing1
OK

The problem with this is a) this is a temporary account for testing In-App Purchasing, and the Apple site knows that. Why all the security? And b) Since I’m never going to remember “Testing1”, I have to write it down (and write about it in my blog). Anyone who finds my password list now knows my “secure” password.

While this is no big deal for the testing account at Apple, it’s a big deal when it’s my bank account. I have a series of mixed alpha-numeric, non-dictionary-word, very secure passwords committed to memory that I use for my truly secure accounts. But if one of those doesn’t work at a site because it doesn’t meet their rules, I have to make up another, then write it down. Once it’s written down, it’s not secure.

At Laridian, I don’t think we put any restrictions on your password. Even though almost one thousand of you use “password” as your password, we’d rather have you be able to remember it than force you to make it unguessable then have to write it down.

PocketBible 2 for iOS

We’re just about to release an update to PocketBible for the iPhone/iPad. This version adds some often-requested enhancements and some new features that you probably didn’t even know you needed.

First, we’ve added the ability to select any text and copy it to the clipboard (what the iPhone calls the “pasteboard”). You’d think this would’ve been a standard feature of the program from a long time ago, but since we wrote our own HTML rendering code, it all had to be implemented by hand — including the cool magnifying glass that shows you what you’re touching as you select text and the lollipop-shaped “drag handles” that let you expand the selection.

Next, the multi-paned user interface was enhanced to allow you to represent each pane as a tab. This lets you easily jump from a Bible to a commentary and back by just selecting a tab. This feature was further augmented with the ability to open all your books in one operation. Your books will open in five tabs/panes labelled “Bibles”, “Commentaries”, “Dictionaries”, “Devotionals”, and “Other”. If you don’t have any books in a particular category, that tab/pane is not shown.

For those who take notes in the expanded toolbox, you’ve been frustrated by the fact that expanding the toolbox covers any open books beneath it. As a result it can be hard to both follow the Bible text and take notes (or preach from your notes). We’ve modified the behavior of the toolbox so that it switches you into tabbed mode if you’re not already there, then moves the current book out of the way of the toolbox. Now your Bible can be displayed in a narrow column above, below, or to either side of your notes. Very nice.

Two major new features are introduced in version 2. First is what we call “Autostudy”. By simply selecting a verse (or a word), you can quickly get a report showing everything your library has to say about that verse/word. While Autostudying a verse, you’ll see that verse in all your selected Bibles, the verse with Strong’s numbers if you have one of our Bibles that contains Strong’s numbers, definitions of every word in the verse from your selected dictionaries, definitions of all the Strong’s numbers in the verse from your selected Strong’s dictionaries, and all the cross-references for the verse from the Treasury of Scripture Knowledge. You can select which books and Bibles are used by this feature and in what order the material appears.

When Autostudying a word, you’ll see how many times it occurs in each of your Bibles, what Greek or Hebrew Strong’s words are translated to that word, and the definition of those Strong’s words and the selected word from your dictionaries.

Autostudy reports can be browsed in PocketBible, saved to PocketBible’s public folder (and from there transferred to your desktop computer through iTunes), copied to the clipboard, or printed to an AirPrint-compatible printer.

Finally, PocketBible now has the ability to speak any Bible or reference book you own. Simply purchase a voice (eight voices in two languages are available) using In-App Purchasing in PocketBible or at our website, then select the text you want to read. You control the volume and can even have PocketBible read while your iPod music plays in the background. You can set PocketBible to start reading at a particular verse and just keep going until you tell it to stop, or give it a specific passage to read.

The basic PocketBible program with the same features as the current version (1.4.7) will be free. The advanced features described above will be available for a nominal fee, either as an In-App Purchase or at a lower price at our website.