Books I’m about to (re)read

I’m heading up to the Vancouver for the Olympics this weekend and hoping to catch up on some reading on the trip. I’ve built up a bit of a backlog of books I want to read or re-read and I’m going to try to make a big dent in the list during the train ride (and while waiting in line for will-call tickets).

First on the list is Saul Alinsky’s Rules for Radicals. I’ve been meaning to read it for a while and I’m looking forward to seeing what people love (and hate) about it. second book on the list is The Checklist Manifesto. Atul Gawande spoke on MS campus recently and his talk inspired me to take a closer look at his book.

There are two other books on my re-read list. Both are controversial in that people seem to either really, really love them, or really, really loathe them. The books couldn’t be more different, but the value in both of them to me is beyond the printed word – the value is between the lines, in the thoughts and ideas they bring out in me every time I read them. ZATAOMM is a classic and a book that I read every few years, or every time I change jobs (whichever comes first). I’m  also going to re-read Quality is Free. A lot of software folks hate this book. At face value, of course, application of manufacturing approaches to software often fail, but the point (to me at least) is to remind me that quality can be improved through processes and culture change and it always gets me thinking of new ideas for improving software quality and building a quality culture.

That’s probably more than enough reading for a short trip, but I’ll bring at least three of those with me just in case there’s more waiting than I anticipate. I think Rules for Radicals is the only book that’s not commonly read among my peers, so I’ll plan to share any interesting insights in a mini book report once I finish it.

Ride the Gravy Train …

I give presentations to teams at Microsoft often. Some teams want a talk on a specific topic, and other teams just ask me what I want to talk about. It’s a good opportunity for me to try out different ideas and see if they have merit. I imagine only 10-20% of these talks would have any interest outside of MS (I think the same percentage of my external talks are interesting to MS folks too).

Anyway, for a presentation coming up in a few weeks, I’m sharing random bits of career advice. The title of the talk is Ride the Gravy Train …and other random career advice. I’ve collected a random assortment of interesting/bizarre/weird career advice over the years, and thought it would be fun to throw it all together into a presentation. I’ll likely use the backdrop of my own career as a storyline for the bits of career wisdom, so I think I can get it to flow fairly well.

Some samples include:

“Always put yourself on the steepest learning curve” – this was advice I received indirectly from Jim Allchin (via a Distinguished Engineer I was talking to). The idea is that if you’re not challenged, you’re not going to grow. I can think of at least 10 examples from my career where I was in so far over my head, I had no idea how I’d ever be successful – but I figured it out, and the experience of crawling my way out of the hole was huge.

Almost contradictory advice from another DE was this: “If you have a great manager who takes good care of you, Ride the Gravy Train”. Good managers watch out for your career and unblock paths you never even knew were blocked for you.

Another one I heard recently was “Sometimes, it’s a beauty contest” – meaning that doing the work isn’t always enough. Sometimes you need to put some lipstick and makeup on your work and show it around to people who matter.

I have several more, but I’d love to hear yours if you have them.

Another Take on the Five Orders of Ignorance

 

I came across a post this weekend about different types of knowledge It’s a well written post that calls out one of my favorite topics – you don’t know what you don’t know. I think the Five Orders of Ignorance (or my tribute to the five orders here) are brilliant, and the author nails Armour’s zero, first, and second level ignorance with his take on knowledge (described as “shit you know, shit you don’t know, and shit you don’t know you don’t know). 20I (read two-oh-eye) – what you don’t know you don’t know (aka the unknown unknowns) are a big reason why we suck at scheduling. Think about it – when we throw out estimates for how long a particular task will take, it’s often half guess, and half padding because we know “stuff” will come up (yes, there’s a lot we can do to make scheduling more accurate too, but that’s a topic for another day).

IMO, there are two pretty big things missing from this article. The first is a discussion of suitable methods to determine what we don’t know we don’t know (aka Armour’s 30I). A passion for learning, critical thinking (and the knowledge or acknowledgement of 20I) all help us identify and solve the unknown unknowns. The way we learn is to discover what we don’t know we don’t know, make it something we (just) don’t know, then make it something we know. We move knowledge down through the orders of ignorance – without a method for discovering what we don’t know we don’t know, it’s just a problem that we’ll never solve (or never know about). For some, I suppose that’s fine, but not for people who are interested in learning.

The second point is that the author doesn’t acknowledge Armour. What’s great about this is that I don’t think it was on purpose – I’m pretty sure the author just didn’t know that Armour had already discussed the same topic in depth. The unknown unknown’s will get you every time!

The Perils of Parables

I’m a fan of The Pragmatic Programmer, and often use the parable of boiled frogs (which I first read in that book) when talking about organizational change. The concept is simple enough – rather than put the frogs (people) in boiling water (changing everything at once), put the frogs (people) in cool water; then slowly heat up the water (change things) until the water is boiling (you’ve reached the change you want). This technique works well for process-y things like cranking up which compiler warnings or fxcop rules you want to turn on, or raising the amount of code coverage you want developers to cover in unit tests.

The boiled frogs approach doesn’t always work as well with organizational change. With compiler warnings, for example, once you’ve reached your goal, it doesn’t “hurt” anymore – your comfortable in the boiling water. If you change the direction of an organization little by little, people may not notice right away, but eventually, they will notice that they’re sweating a lot and that their skin is bright red.

Of course, many people survive organization change – things change and they either like it, or are ambivalent to the change. Organizational change is an adaptive  challenge (as opposed to a technical challenge).  In Leadership on the Line, Heifetz and Linsky discuss adaptive challenges in depth and point out that with changes like this, sometime there are casualties – that some people, processes, etc. that just don’t survive the change. Some people may not have the capabilities to take on a new challenge, and in other situations, people just aren’t comfortable, or feel they’re at their best once the water is boiling. Casualties are ok as long as the reward of the organization change outweighs the loss.

I guess I am a casualty.

I joined the Engineering Excellence (EE) team at Microsoft nearly five years ago. Just over two years ago, I took over the Director of Test Excellence title. In the past five years, I’ve taught courses to thousands of testers, and met and worked with just about every senior tester and test manager at Microsoft. The work has been fun, challenging, and rewarding.

But EE is changing.

The changes in EE are good – maybe even great, and I think the org is headed in a solid direction – but the actual work has moved so far from what I really enjoy doing that I can’t do it anymore. I’ve wondered for some time what I’d do after I left EE, but I finally had the revelation that I needed to change something in December. Two things happened in one week that (as a colleague often says) made the scales fall from my eyes. The first was a team offsite, where we discussed the direction of the organization. The discussion was about how to deal with the parts of our job that were unfamiliar to us. Somewhere in the middle of wallowing and discussion, the lights went on – the job wasn’t for me anymore. The second “sign” was in the results of a medical physical. I signed up for an in depth health screening as part of Microsoft’s benefits, so I ended up getting two physicals in one year. The only problem with my second physical was that my blood pressure was up nearly 30 points. I thought it was a fluke since I’ve been 110 over 70 for as long as I can remember, but in a follow up checkup, it remained at 138 / 80.

I took the next three weeks away from work. I’m not sure if it was being away from work, or the mental realization that it was time for something new, but I’ve been able to drop it quite a bit since then. I’m confident that I can get it (and keep it) back completely under control from now on.

So, while I’ve been avoiding blogging and twittering over the last month, I’ve interviewed with some non-MS companies and have talked to a variety of Microsoft groups. When I first joined EE, it was really weird for me not actually testing products. I thought I would get used to it, but I never did. If I could change one thing about the last five years, I would have found some way to do more hands-on testing. One thing I heard (both directly and indirectly) as I looked around was worry that I was “stale” – that I had been away too long to be relevant. I suppose that will be something I’ll have to “earn away”, but I hope that it’s just a perception and that I actually know what I’m doing.

The good news, is that I’ve found and accepted a new job. I’m staying at Microsoft, and will be working for someone who I think is one of the best managers at Microsoft. The org is small enough that I think I can make a big impact, and large enough that it will be a challenge. Mostly, I’m working on a team that values experimentation, trust, and fun. I’m reunited with testers I’ve worked with a dozen years ago, and others that I’ve met and mentored as recently as a few months ago. I’m excited and can’t wait to be a “real” software tester again. I expect it will also give me an endless supply of blog fodder, and that the mental joy of software testing will give my health another boost in the right direction.

My last day in EE will be Feb 28. In the meantime, I have a mountain of transition stuff to work through, but do expect to be back on top of my social media game shortly. It’s been a fun ride, but I’m looking forward to even greater challenges.

Listening to feedback

I have half a dozen different blog posts started but I thought I’d write this one instead. When you listen to customer feedback, you need to treat the good and the bad equally. If some customers say “wow – this is awesome”, and some others say “this is awful – are you on crack?”, either they’re both right, or neither of them are right. People base their opinion on their experience. It’s unfortunate that you created polarizing experiences, but that’s what happened. If  you write off the negative comments as flukes, it’s only fair that you say the same about the positive comments.

We get feedback on the courses we teach for testers at Microsoft. My team is pretty good at reviewing feedback and making adjustments as necessary. I remind my team of the same thing. They need to treat the positive comments (“the instructor made the class awesome!”) and the negative comments (“the instructor was an idiot”) the same. Either throw them both out, or treat them both as valid. Obviously, you can play the balance game. If 20 students said “great”, and 4 said “sucks”, then you’re probably on the right track (although you’d want to self-evaluate on why the polarity exists in the first place). It’s a frequent topic of discussion, but one that I think everyone understands.

The concept came up again this week when a teammate pointed out that someone commented about me on the mini-microsoft blog. The comment in question was mostly positive, yet it was in response to something negative (which, in full disclosure, I replied to a week or so ago). In this case, I either have stale ideas and have some talent, or neither. I don’t really care either way, but I suppose I’m happy for the attention (there’s no such thing as bad publicity).

The important lesson to learn is that there’s no bad feedback, and no irrelevant feedback. There’s just feedback – it’s your choice to listen to it or not.

Why is the Weasel angry?

I’m surprised that many people are still asking me what an angry weasel has to do with software testing. The answer, of course, is nothing. I’m surprised however, how many people can visit my site at angryweasel.com/blog and never check out plain old angryweasel.com (where I happen to share the story of where the name came from).

I expect that this year, among other things, will mark the return of the Weasel – stay tuned.

My last fifteen years (part 5)

(part 1 is here)

(part 2 is here)

(part 3 is here)

(part 4 is here)

I’ve been in the Engineering Excellence (EE) team at Microsoft for nearly five years now, and the time has flown by. The job is completely different from a typical test role, yet almost all I talk about is testing. I’ve used my time in this group to continue to learn about testing, but to this day, I still miss the ebb and flow of adrenaline that comes from working on a shipping product.

The first big project assigned to me in EE was to design a course for our senior testers. I had no idea what I was doing, but I after talking to dozens of people around the company and receiving some critical help from some of my new peers, I ended up with a course that has been well received for going on five years now, and is relatively unchanged from the original. This work led to a ton of research over the last five years on growth paths for testers (one output of that research is in my pnsqc paper from 2009). I think of the work I’ve done in EE, this work on growth and career paths for testers is what I’m most proud of.

About a year and a half after joining EE, my manager left to join another team at Microsoft. Less than another year later my “new” manager left and I, for some reason, decided to step into the director role on the EE team. I’ve never been completely comfortable in a manager role, but after some long talks with my peers (soon to be employees) about the move, I decided to give it a shot. The core of my work didn’t change much, but I did spend more time on “overhead”  – budgets, scheduling, etc. I’ve had a chance to learn a lot in this role, and a chance to work with test leaders all across the company.

I’ve also used my time in EE to study. I’ve probably read a hundred books about testing, management, and leadership; taught dozens of classes and given more internal talks than I can count. I’ve spoken externally as much as I can handle, and wrote more about testing than I ever imagined I could. All in all, I have a lot to be proud of about the last few years of my career.

What will the future bring for me?

I’ll tell you later.

My last fifteen years (part 4)

(part 1 is here)

(part 2 is here)

(part 3 is here)

When I joined the CE team in 2000, l knew nothing about embedded systems, and exactly as much about non-Intel processors. Furthermore, I didn’t know what I was supposed to do on the team. The Pocket PC had just come out, but the team was already pretty much set for the next release. Given my recent kernel experience with Windows Millennium, it made some sense for me to work on something similar on CE. I was still in the reluctant test lead role at this time, so they assigned the kernel and file system testers to work for me. The problem was, that they had it covered so well that there wasn’t much left for me to do. They gave me some other stuff to own (like drivers), but they had it covered to. Sure, I got to help out, but I was sort of turning into one of those managers who does nothing but manage.

But I still had some time, and I was looking for something “technical”. One day in a meeting, I discovered that they were going to punt/postpone every single bug and feature in the shell code (shell is the GUI on top of the OS – the basic explorer shell on windows). I volunteered to do the work and for some reason my manager and hid counterpart on the development team agreed. My role became the Kernel/Filesystem/Driver Test Lead / Shell Developer. I can’t recall how I actually survived this dual role.

Working on the shell was fun, but more importantly, it was a turning point in my career. When I agreed to take on the work, I thought it was my stepping stone to a software development position. I worked closely with the dev manager and hit all my deadlines – but I also discovered something important about myself. The workload was fairly light. I was supposed to fix 40 or so bugs and add 4 features. I love fixing bugs (actually, I love the investigation process). I love to figure out why things don’t work. The features on the other hand, were sort of ho-hum. The only thing I remember writing from that time was the feature that calculates the daylight savings time rollover. I’m not sure if my code is still running in windows mobile, but at one time it was. When I finally finished all of the work and had some time to reflect I realized something important.- I didn’t really like being a developer. I was certainly capable, but the core of the work didn’t align with the core of my passions. As soon as I finished my features and fixed my bugs I met with my manager and I told him that I wanted to be a full-time tester; no more development work, and no more management. This was probably the first time in my career I really took testing seriously.

Not too much later, I became a test architect. That title doesn’t really denote a specific role at Microsoft – at the time it was more of a fancy title they gave testers in senior roles. I started meeting with other test architects (we had, and still have, a weekly meeting). There were 6 or so of us at the time and we had a handful of projects we’d work on together. We gave a presentation to Bill Gates in December of 2000 (I remember, because the presentation was on my birthday), and it seemed to go well. At the same time, I began to study testing. I started reading books about testing. I found contradictions, good ideas, bad ideas, and things that made me think of new ideas. I know a tester who says that there are no good books on testing, but I disagree completely. Every book on testing is good as long as you read it critically and use the knowledge in the book to confirm or challenge your own ideas.

So, I studied, I read, I tested. I was having fun experimenting and trying new ideas out. I began blogging while on the CE team – mostly writing about the testing tools we used for Windows CE and sharing some of the utilities and slides I was showing at developers conferences. It was a time of a lot of growth for me, but by 2005, I felt I was ready for something new. I had been in CE for about 5 years, and we were wrapping up CE 5.0. One of the testers I had mentored for several years had the passion and knowledge to be a test architect, and it made sense for me to step out of the way. I wasn’t sure where to go, so I asked Harry Robinson if he had any ideas. Harry was in Engineering Excellence at the time, and I thought he may have some insight into what groups could use someone like me. As it turns out, Harry told me that he was leaving Microsoft, and that I should apply for his open position. So – I did, and in April of 2005, I transferred to the Engineering Excellence team.

My last fifteen years (part 3)

(part 1 is here)

(part 2 is here)

When I joined the Windows Millennium (I usually cover my mouth and mumble when I mention this product) team I was given the opportunity to join either the development or test team. I met with both the dev and test managers and disliked the test manager much less :}, so my mind was set.I also enjoyed testing a lot – I liked figuring out how things worked (and figuring out how they didn’t work). One thing that bugged me during Win98 development was that we stopped testing on the debug version of windows. The debug build caught all kinds of errors that may not be caught until much later (or ever) (sort of a fail-fast mode) – it was a great way to make sure applications, libraries and drivers were all written and behaving well. Unfortunately, it suffered from broken windows – by the time the winme team was formed, it wouldn’t even boot without going through dozens of breakpoints in the debugger. When you got that far, a bunch of the other windows apps would hit breakpoints. The big problem was that the app breaks were mostly benign (e.g. bad NULL parameters), but because it was such a pain to run, nobody could take advantage of all of the other checks built into the debug build. The best part was that when I said I wanted to fix it, our management team told me to go for it. The initial job was just a lot of error / parameter fixing. It only took a few days until the debug OS would boot, then I fixed all of the apps I could. At this point I had to work on the “play nice with others” part of my job – I had to get a bunch of teams outside of windows to fix their application bugs. Eventually, I got most of them fixed, and you could actually “self-host” (use the os for most daily work) the debug build. We even used to play network games on the debug build on Friday afternoons! We did a lot of enhancements to the debug build – memory leaks and memory corruption were pretty easy to track down and fix, and we found a ton of other pretty bad errors (just not all of the errors customers found)

Along with debug windows, I also was asked to “maintain” the win9x debugging tools. The kernel debugger ran as a TSR that loaded at boot time. It communicated over a serial cable (although we later made it work over 1394) to a smart terminal. It turns out that “maintenance” of the debugger also included a bunch of changes and enhancements. One bit of context is that the winme team was “only” about 200 people (possibly less), but at least a thousand people around the company tested and dogfooded winme, and most of those used the kernel debugger. This meant that if I messed anything big up, that I could have a thousand people blocked. Luckily, that never happened – I made it through the product cycle relatively unscathed.

Along the way my manager tricked me into becoming a lead. He gave me more work than I could handle and when I complained he gave me “the new guy starting next week”. Turns out that guy was pretty smart and helped me look good for quite a while (we still have lunch every few months to this day). I ended up with 4 or 5 direct reports – one helping me with debug windows and the debugger, and the others working on the overnight stress infrastructure. I spent most of the day every day in the debugger and learned a lot. I’d use it to explore the operating system – setting breakpoints on unfamiliar functions so I could step through and see how they worked. I would change values (including return values) and watch what happened in untested code paths. I found a few cool bugs this way, but mostly learned.

Just before WinME shipped, our GM was promoted to VP. He was going to take over the Windows CE team and in the summer of 2000, he took 20 or so of us with him. In just over 5 years at Microsoft, I had worked on win95, win97 (the product I was working on before PST split into windows and IE teams), IE2, IE3, win98, win2k and winme (and 3 blog posts). The good and bad news is that I can probably finish the next 10 in one more post.

My last fifteen years (part 2)

(part 1 is here)

My official full-time start date at Microsoft was June 6, 1995. The first release candidate for Windows 95 was June 8, so in a way I started just in time – I started in time to get the Win95 ship gift (limited edition of windows 95), and also got a watch commemorating 20 years of Microsoft. I think we released the US version sometime around the 24th of June, and as a full time employee, I was technically allowed to attend the various ship festivities. I remember a gathering behind building 4 where way too much Dom Perignon was poured on people’s heads, as well as a larger party at the Shriners club in Seattle. I attended both, but I sort of had to sneak to the first one. I had a lot of responsibilities for the Asian versions of Win95, and I was supposed to be making sure that nobody in Japan ever had anything to complain about when running windows 95. But, I figured that since I gave up my overtime to get a blue badge, that it was ok if I went to check out the parties (note that I did the same thing for the official August 24 launch party). Windows 7 shipped a billion or so languages on the initial release day, but back then, the goal was to ship all of the top languages within 90 days (don’t ask me what “top” meant – what it meant to me was that i was working on Japanese, Chinese and Korean Win95 until the end of August). Eventually, we did ship, and it was time for me to be part of the early product cycle for the first time ever at Microsoft.

So, for a few weeks in September (I think) of 1995, I wrote some completely kick-ass tests that eliminated some of our brain-dead manual testing (I know I need to watch my words – not all manual testing is brain dead, but the testing I replaces was). I wrote a controller that applied configurations to multiple machines (think Japanese computer and share names), then ran a suite of network testing against those specific names to verify there were no problems with any Asian ideographs and network connectivity. I showed my (still awful) boss, and he almost smiled. He was so excited, in fact, that he set up a demo with his boss for the following Friday. I spent the weekend tweaking and polishing my suite to make sure it would survive the demo like a champion.

But the demo never happened.

Instead, on the day before the demo all of “PSD” (we were called the Personal Systems Division at the time) were hauled off to a nearby conference center (the MS conf center wasn’t built yet) so Bill could talk to us. He talked about his Internet Tidal Wave memo and said some other stuff that I’m sure was important. All I know is that by the time I got back to my office, I was on the Internet Explorer team.

I worked a bit on IE 2 (although, to this day, I can’t remember what I tested). IE3 was the “Netscape killer” release, and was on a 6 month schedule (Feb-Aug, 1996). I owned the feature that let you select the language of the page. At the time, languages weren’t auto-detected – instead, you clicked a little globe in the status bar and selected the language you wanted the page to display in. My testing consisted mostly of creating a bunch of web content and putting foreign characters in every html element I could find to ensure that they displayed correctly. I also remember that we changed our behavior with named entities. Before IE3, for example, a Russian page could display the character “?” by using the two named entities. One was the character code point – e.g. &196;. The other, unfortunately (blame front page), was by using the named entity for the code point in English – i.e. Ä (“A” with an umlaut). This, of course, is stupid,  but the change was going to break hundreds (the 2010 equivalent of hundreds of thousands) of web pages. I remember a lot of panic and worry among some of the managers. I also remember suggesting that I write a tool to help web masters fix their broken html. I wrote the tool in less than a day and received heaps of praise. Bing tells me that there’s still one web page out there about this tool – kind of funny (and embarrassing, since I’m sure it’s the tool is nothing I’d be proud of today). I also wrote some IIS server extensions that had something to do with language detection. It was interesting – and fun, but I knew that web browsers weren’t my calling.

A few weeks after IE3 shipped, I re-joined many of my friends from the previous year and joined the windows 98 team. The first project I worked on was a suite of networking tests – this time written in C and tested at the API level. I felt like a real programmer for the first time and got a lot of mileage from that little test suite. It was flexible enough to test the majority of network functionality against a variety of servers (anyone remember Banyan Vines?). I was on the international team, and as one of the few people on that team who could program well, I also owned a lot of international GDI features (the component that draws text and images to the screen). There were a lot of interesting issues drawing and printing Asian ideographs – I worked a lot with internal (e.g. Office) and external customers to isolate bugs they had run into on windows 95 so we could determine how (or if) to fix them for windows 98. I learned a ton about fonts – at one time I could tell you everything about how a TTF file was put together and explain details of font smoothing for hours. Today I remember only the basics, but I remember lots of reading and experimenting. Eventually I ended up owning GDI and User (user is the component that does windowing, menus, and controls) for all languages of win98. It made me learn a lot about how windows applications work, and a lot more about application compatibility issues (many app compat issues were rooted in the GDI and User components). Eventually (spring, 1998), windows 98 shipped. It was supposed to be the last version of “consumer windows” ever, so the team disbanded, and I got a job working for a pretty cool guy named Brad.

One of the things I love about Microsoft is that you can change jobs completely without leaving the company. The bulk of Brad’s team tested USB on NT5 (later named Windows 2000). A few others owned testing some of the core USB devices and related peripherals. I was in the latter group and tested video capture devices (aka cameras and TV tuners). Most of my tests were written via DirectShow APIs, so it was an opportunity for me to work on COM and C++. After a while, I really got the hang of it. One of my personal biggest successes at the time occurred when I discovered that I needed a generic library function – something that DShow probably should have provided, but didn’t. I wrote the helper function and it worked well for my testing. Of course, just a few days later, DShow added the API so I didn’t need mine anymore. The really cool part was that my implementation was almost completely identical to the API version – it made me feel like I knew what I was doing. Of course, there should probably have been better communication so I knew that the change was coming, but oh well.

I also did stupid stuff. One of the things you have to do if you’re playing with video and audio via DShow is connect all the darn pieces together. It’s sort of like this:

I would end up creating what I called “the wedge” – where the inner if in my big connection thingy would start on column 70 or something like that. It made sense to me at the time, but … seriously, yuck.

Firewire/1394 video cameras were new at the time – I had one in my office that I could control via an app I wrote (it eventually became the 1394 camera SDK app). I also had this really cool device that could emulate television signals. I had a lot of fun with that one. This was also the first time I played with code coverage. Even then, I realized that the biggest benefit of CC was finding holes in my tests.

Brad also assigned me two “special” projects. One was some work for Windows 98 Second Edition (win98SE). I wrote (ported, actually), the power management utilities from Windows NT to 98SE. It wasn’t really that hard, but it was cool to write software that went in the box rather than just tests. The other project was this thing called Pandora. Pandora was a DVR (although I don’t think that term was even around yet). I think Tivo was announced at the time, but not out yet, so this was pretty cool stuff at the time. I was the only tester on the project and it was a blast. Unfortunately, however, for reasons I was never told, the project was cancelled.

Then, less than a year after the win98 team disbanded, marketing pushed hard for another windows 9x release. Phone calls were made, and before I knew it, I was on the Windows team again working on Windows Marketing Millennium Edition.