Both ears are now quite clearly up.

所有我感兴趣的资料,webdesign,webdev,linux,etc.Enjoy。
Both ears are now quite clearly up.

The Release Engineering:Future bugzilla component alternately inspires feelings of sadness, loathing, and contempt…and that’s just within the RelEng team!
I’m certain most developers first response to having their bug moved to the Future queue is, “Oh, look, my bug has fallen down a well.” Historically speaking, that may not be far from the truth.
Why does the Future component make people get punchy? For a long time, the Future component has lacked a decent description, so developers don’t know what it means when their bugs are moved there. Many have started hording their gigawatts in anticipation.
Bugzilla currently has the following small description of the Release Engineering:Future component:
“For longer term projects that have been agreed should be done, but have no immediate plans to so. These are not be part of the regular recurring triage. Advanced planning and placeholder goals for next quarter also go here.”
Despite the grammatical errors, this description is mostly accurate, but what does it actually mean:
Remember: this description is for the Future component ONLY. The RelEng team continues to pick up and work on bugs that need to get done on a daily basis.
I’m thinking about how to improve this description, and will get the description updated in Bugzilla once I have achieved some rough consensus. In the meantime, I’ve posted this description of the Future component in the wiki as an ongoing reference.
The (Ever-Increasing) NumbersAt the time of writing, the Release Engineering:Future component has 343 bugs in it. This number has grown steadily over the past year despite having more release engineers on staff, and having made a great many improvements to our release automation and our continuous integration infrastructure.
Our turnaround time for bugs in the Future component is also not stellar. At our urging, the Mozilla Metrics team recently started setting up a dashboard to give us various statistics on our Bugzilla usage. Bugs don’t get fixed in the Future queue, so it’s hard to make truly accurate assessments here, but there are a lot of aging bugs in there. According to the numbers, fully 50% of the bugs in the Future component are older than 1 month and more than 25% are older than 6 months. How this compares to other teams or areas, I can’t say, but it certainly makes me empathize with developers who feel their Future-ed bugs have gone walkabout.
If it makes you feel better in a sadistic way, the majority of bugs filed by RelEng team members go directly into the Future queue. We’re not overly happy about it either.
Things are getting done, though. For example, over the past month, the number of non-Future, release engineering bugs that are actively being worked on has gone from a low water mark of 130 up to over 200 today. For comparison, over the same period, the total number of bugs in the Future queue has slowly crept up from a low of 302 to 323. Mozilla is growing along so many axes that sometimes it feels like keeping the increase in the number of Future bugs to a linear relationship rather than exponential one is an accomplishment in itself.
So how do we stop the increase and start wrestling the Future component back under control?
The first step is triage. Starting this Thursday, February 11th, the RelEng team is going to have bi-weekly triage meetings to specifically prune down the Future queue.
As part of the triage, we’re going to be touching every bug and updating the whiteboard field with searchable tags. Our goal here is to make it easy to find classes of bugs in the Future queue so that duplicates and overlap can be easily eliminated, and fixes can be batched as much as possible.
We’ll be keeping a list of the tags we’re using in the wiki in case you want to follow along.
There are some classes of bugs that we won’t be able to eliminate (e.g. future goals), but hopefully within a few months, we’ll have the Future queue back under control.
It won’t be a quick fix, but it’s one we’re committed to.
I’m a bad conference organizer.
Why? Because we opened the An Event Apart 2010 schedule for sales back in, um, flippin’ November, and I never mentioned it here. Cripes, I never even posted when we announced the lineup of cities. I could go through the great big long sob-story list of reasons why 2009 was really tough and blah blah blah, but when you get right down to it, I fell down on my job.
Okay. So. Time to correct that.
(deep breath)
Hey everyone, check it out: the complete tour schedule for An Event Apart 2010! Woohoooo!
We’ve got a pretty killer lineup, if I do say so myself. You can get the mostly-complete list from our opening-of-sales announcement last November. It lists the people we had confirmed at the time; there have been a few additions since then. Check out your city of choice to see who’s going to be there! (But always remember that speaker lineups are subject to change: speakers are people too, and life has a way of interfering with schedules. I myself had to withdraw from An Event Apart Boston last year due to a family emergency.)
The price to register for these two-day, one-track Events is the same as it was in 2009, and there are educational and group discounts available for those who are interested.
But wait, I just said “two-day” when the first show of the year is clearly three days. What gives?
Seattle is the site of our first-ever A Day Apart, a full-day workshop that can be attended on its own or as part of a full three days of Event Apart ecstasy. And the inaugural Day Apart will be nothing less than a detailed plunge into HTML 5 and CSS3 with Jeremy Keith and Dan Cederholm. Jeremy handles the markup; Dan gets stylish. It’s going to be fantastic. I’m going to be in the back of the room for the whole day, soaking up as much as I can.
If you want to attend just the workshop, it’s $399 for the whole day if you buy an early bird ticket (available through March 5th). The price goes up $50 when early bird ends, and another $100 if you show up at the door. But I wouldn’t recommend that last, because I don’t think there will be any tickets available at the door. Again: if you show up unannounced on the day of the workshop and ask to buy a ticket, we will most likely have to turn you away, because I expect that there won’t be any seats available.
On the other hand, maybe you’d like to experience more than just one day of AEA goodness. Maybe you’d like to go whole hog and attend both the two-day Event Apart and the subsequent Day Apart, soaking up all the knowledge and enthusiasm and camaraderie that typifies An Event Apart. And who could blame you? If you do that, then the total early bird price for all three days is $1,190, whereas buying the event and workshop passes separately would total $1,294. That’s right: you actually get slightly more than $100 off the cost of the workshop if you attend all three days, over and above the early bird discount. (Or you can think of it as getting $100+ off the cost of the conference. We’re not fussy.)
As it happens, these three-day passes have proved quite popular. So if you want to get your hands on one of those—or on any Seattle tickets, whether one, two, or three days—I wouldn’t wait too long. Our internal analyses suggest that there will come a time, some time before the doors open on April 5th, that the ability to buy a ticket will cease to be. It may even pine for a fjord or two.
As for the four shows that come after Seattle, well, they’re looking pretty popular too.
I know I say this every year, but I’m really excited about what we’ve got planned for the year. Jeffrey and I constantly and (we hope) consistently strive to create an event that we ourselves want to attend, and that’s absolutely true of the shows and workshop we have planned in 2010. I can’t wait to hear what the speakers and attendees have to share. Hope to see you there!
Postbox now integrates with the Mac OS X technologies and applications you rely on most to get stuff done. Here’s what’s new:
Mac Address Book Support
Postbox provides read and write support for the Mac Address Book. Keep all of your contacts in one location and sync them with your iPhone or MobileMe service.
Send Meeting Invites with iCal
Apple’s iCal can now use Postbox for sending calendar notifications.
Search for Mail Using Spotlight
Postbox provides full support for Apple’s Spotlight to search through message bodies, message header information such as To: or From:, and attachment names.
Exchange Images with iPhoto
You can export photos directly from Postbox into iPhoto, and iPhoto will use Postbox to send photos as well!
Send Link from Safari
Easily send a web page link from Safari using Postbox. Very handy!
Lookup in Dictionary
Direct text-to-Dictionary lookups will help you quickly pick the perfect words.
Drag-to-Dock Message Creation
Dragging a file to the Postbox icon in the Dock will create a new message with the file attached.
Learn more about these new features and how to use them in our Quickstart Guide.
And now, with our new Refer-a-Friend Program, we’ve created an exciting way for you save on Postbox, or even get Postbox for FREE! See our Refer-a-Friend Program Page for details.
Our Refer-a-Friend Program is easy! Tell your friends about Postbox, and earn $5 each time someone purchases with your coupon code! Refer six friends and Postbox is effectively FREE!
Step 1 - Save $10 on Postbox!
Use your search skills. Find a coupon code to purchase Postbox for just $39.95 $29.95!
Step 2 - Share your Coupon Code
We’ll give you your own coupon code for “$10 Off Postbox.” Share it via Facebook, Twitter, your blog, email… anywhere.
Step 3 - Make $5 each time someone uses your code!
You get it - make 6 referrals and we’ll send you $30 - the price you paid for Postbox. Any more… and it’s all gravy.
There you have it. Postbox for about the price of a pizza, plus a way to earn it all back and give your friends a discount. Everyone wins!
To get started, search Google or Twitter for a coupon code to Save $10 on Postbox today! If you are an existing customer, simply select License… from the Help menu, and click Get Referral Code.To learn more, please see our Refer-a-Friend Program page, read our FAQ, or review the Terms and Conditions.
A special “Thanks!” to Charlie Wood of Spanning Sync for his help and advice on the development of this program.
Recently, I found that I needed my chrome Mochitest to wait for a XBL binding to apply, before continuing the test. For the end-user, waiting is hardly an issue - by the time they see the new user interface, all the bindings have applied. Mochitest (and most other automated test harnesses) runs straight through, and brakes for nobody. In some cases you can pull some trickery with nsIThreadManager, convincing Firefox to wait... but that's hardly reliable.
So I came up with a three-part solution.
This new test harness, which I call PendingEventsTest, adds a layer of complexity on top of SimpleTest. Each test function is added via PendingEventsTest.addTest(), and you can pause for a DOM event with PendingEventsTest.addEventLock(). The whole test sequence can abort with an error by calling PendingEventsTest.abortFail(). You can advance to the next test function in the sequence with PendingEventsTest.asyncRun() or PendingEventsTest.run().
There's more complexity to it than that, of course. To move data from one test function to another, I also added "payload" support, for storing a generic object. Also, this is written for chrome Mochitests - it will likely fail in content Mochitests. Still, this new test harness helped me finish support in Verbosio for my equivalent of the <xbl:children/> element in markup templates.
Lastly, it (and the logging service I wrote a few weeks ago) is licensed under MPL 1.1/GPL 2.0/LGPL 2.1, so anyone who wants to borrow this for Mozilla code is welcome to. Cheers!
On Friday night our family stayed with my parents on a boat up at Mahurangi, in Lagoon Bay. Easterlies had been blowing steadily for a few weeks and probably pushed a lot of plankton inshore, which helps explain what we saw that night.
About 10pm, after most of the crew had gone to bed and it was very dark, I noticed unusual flashes of light in the water. It was obviously bioluminescence caused by plankton, but far more intense than I've ever seen before. Even in still water, there were tiny points of light winking like flickering stars. Anywhere water was disturbed, it glowed brightly. Fish jumped, and the ripples formed bright, expanding halos. You could see moving, oscillating, sinuous lights underwater that I presume were fish swimming. I hopped in the dinghy with my wife and rowed around. The splashes of the oars created amazing flashes and patterns of light, and the dingy left a glowing wake. My wife dipped her hand in the water and it came out luminous.
It was an utterly remarkable experience --- like the bioluminescent forests of Avatar, but with the considerable advantage of being real. (Sorry, no photo --- the lights were only bright relative to the darkness of the night, and I lacked the technology and skill to capture them.)
One common thread running through the many different and interesting WebGL projects out there is that they all need to do vector and matrix math, do it quickly, and do it in JavaScript. To date, developers have either rolled their own, or they've used Sylvester, a fairly featureful vector and matrix JavaScript library.
One of the problems with Sylvester is that while it's fully featured (arbitrary NxN matrices and vectors can be created and manipulated), it suffers in performance because of it. Since this is such a crucial part of a successful WebGL program, I've put together a small package that I'm calling mjs.
mjs is designed around speed and simplicity. For example, it doesn't attempt to stuff vectors and matrices into JavaScript objects. Because the language offers no operator overloading, there's very little benefit in treating these types as discrete objects, and lots of performance and memory usage downsides. Instead, it provides a set of functions for performing operations on vectors and matrices, which can be any array-like object. For any function that returns a vector or matrix, an existing array can be passed in to take the result, or the function can create a new one. Array reuse ends up being important because of the potential for expensive garbage collection churn eating away at performance.
Here's a sample of the API:
var r = M4x4.rotate(Math.PI/2, V3.$(0, 1, 0), M4x4.I);
Note that V3.$ and M4x4.$ are shorthand for creating a new V3 or M4x4 (I wanted to use V3() and M4x4(), but that didn't work out too well since functions have a length property). However, because all they return are just new array-like objects, you could also write:
var r = M4x4.rotate(Math.PI/2, [0, 1, 0], M4x4.I);
If the WebGL types are available, those will be used for newly created vectors/matrices. They are a significant performance boost especially for repeated operations; but for specifying one-off vectors such as the above, literal array syntax is fine.
The rotate function internally makes a rotation matrix, and then multiplies it by the given matrix. So the above could also be written as:
var rotation = M4x4.makeRotate(Math.PI/2, [0, 1, 0]); var r = M4x4.mul(M4x4.I, rotation);
(The last line being redundant given that we're multiplying by the identity matrix.)
All methods that return a vector or matrix take an optional final argument, that of an existing object to reuse. For example:
var m0 = M4x4.$(); r = M4x4.mul(someMatrixA, someMatrixB, m0); // r == m0, so the assignment isn't necessary, but it's handy for chaining // .... do something with r ... r = M4x4.mul(someMatrixB, someMatrixC, m0); // r == m0 still // ... do something else with new results ...
Without allocating any additional temporary objects.
As mentioned before, one of the goals of mjs is performance. Matrix multiplication is one of the most common tasks, so here are some numbers comparing mjs, Sylvester, and native C code. This was run on a Core i7 desktop using a local build of Spidermonkey, which included one patch that's about to go into the tree that fixes the no-reuse tracing case. (Without it, the no-reuse tracing case is much larger because it's never actually jitted.) The test is simple: it multiplies two matrices together in a loop 1,000,000 times.
| Test | Time |
|---|---|
| mjs, JIT, matrix reuse | 140ms |
| mjs, JIT, no reuse | 533ms |
| Sylvester, JIT, no reuse | 5,280ms |
| mjs, no JIT, matrix reuse | 25,833ms |
| mjs, no JIT, no reuse | 26,681ms |
| Sylvester, no JIT, no reuse | 41,996ms |
| Native C++, SSE2, matrix reuse | 71ms |
| Native C++, SSE2, no reuse | 142ms |
(I also have numbers for MSVC without the SSE2 compile flag, but the numbers vary greatly depending on whether the values eventually go to infinity or not; if the values end up trending towards 0, the non-SSE2 code tends to win at around 52ms vs. 71ms; if the values trend to infinity, the non-SSE2 code takes around 11,000ms!)
Those numbers are pretty encouraging -- having native code be only 2x as slow for something like this is pretty nice to see. Granted, this is only a very isolated test, and I'm sure there are some tricks to optimizing the native code case (it's currently just a fully unrolled set of multiplies and adds). The "no JIT" case is less nice, but I'm sure that our Jaegermonkey folks will be all over this testcase (right, guys?). In any case, ideally most WebGL rendering loops will be fully traced in Firefox, so it would be less of an issue.
mjs is still very much a work in progress; it's missing a test suite and a whole bunch of features. You can find it hosted at Google Code, at webgl-mjs. (Side note: I couldn't just call the project mjs because a project called mjs was abandoned on Sourceforget 5 years ago, and Google Code complained.) There's also some documentation, viewable online here.
Bugs and contributions welcome!
Thanks to hard work by a whole bunch of folks, we shipped Lanikai Alpha 1 (the first development release of Thunderbird after 3.0) yesterday. More details about Lanikai can be found on the project page.
This release is a first in several notable ways:
* we're now requiring automated tests to land with most code changes
* the release cycle was much shorter than any development release in recent memory
* we're now having to do development and releases across both a development and a stability branch.
We've already learned a bunch of stuff from all the changes, and I expect that learning to continue for a little while before we're fully in a groove.
Thanks to everyone who has been part of making the release happen!
A common situation I run into is that I have some testcase, I profile it, then I optimize one of the things that looks slow a bit and reprofile. If I'm lucky, then the fraction of time it takes drops from B to A (A
Obviously, what it means depends on both A and B. If we assume that the time taken for the part that wasn't optimized hasn't changed, then the overall speedup is (1-A)/(1-B).
So B - A = 5% would mean a 2x speedup if B is 95% and A is 90%, and only a 1.05x speedup or so if B is 5% and A is 0%. If B is something like 53% and A something like 48%, then you get a 1.11x speedup.
All of which is to say that focusing on the hotspots is _really_ the way to go, if at all possible.
This is a follow-up to Ben’s blog post about the RelEng Sheriff back in October. His post described clearly what the RelEng Sheriff (and more generally, the RelEng team) can do to help developers.
Since we implemented the RelEng sheriff (or “buildduty” as it is more informally called) last spring, developers have been getting better about using the buildduty person as the first point of contact for RelEng issues. I’d like to implore people to continue doing so. There are a few exceptions, of course:
We recognize that different release engineers have different core competencies, and it may be tempting to go “straight to the source,” but please respect our process. The process is in place to limit (as much as possible) the interrupt-driven nature of release engineering work and to minimize the impact of those interrupts on ongoing projects. In many cases, the person with the expertise you need will still end up helping you (we’re all in the same IRC channels, after all), but the buildduty person is specifically committed to helping you, even if only as a thin scheduling proxy for another release engineer.
Ben’s post had a good list things that RelEng can help developers with. Based on actual requests over the past few months, here are a few other services we can offer:
In both the above cases, the best thing to do is talk to the person on buildduty and then file a bug.
Conspicuously missing from Ben’s post was a list of what RelEng can’t do for you. While we can usually point you in the right direction, there are some things that we explicitly cannot do:
Need help finding the RelEng sheriff? Here’s the RelEng sheriff schedule.
This is the third in a series of blog posts (previous: 1, 2) on how Mozilla is using its trademarks to try and make sure everyone gets a genuine copy of our software, for free.
Mozilla has a form where people can report sites abusing our trademarks. And we are very grateful to people who do. Harvey Anderson, the Mozilla general counsel, has recently posted some statistics on what those sorts of reports have helped us achieve.
But we aren't the only people trying to deal with the problem of "subscription trap" sites. downloados.de is a private initiative in Germany educating internet users about the typical set-up of a subscription trap. It comes across like a typical trap site, but when the user makes the final click to send off their personal details and to obtain the software, the website then informs them that they were about to spend money on free software and that they should be more careful next time.
Sodapop turns 9 weeks old tomorrow. The most notable change from a week ago is that one of her ears has started to stand up. Eventually (probably in a week or so) both will be standing tall. The next change, besides weight gain and better manners, will be when more of her silver hair comes in. You can see a bit of it around her eyes, but she's still mostly black and tan.
Sodapop at 8 weeks
Sodapop at 8 weeks 6 days
For those people paying attention (and anyone who might want to update my Wikipedia entry,) Sodapop the yorkie is the third child in our family behind Ptolemy the cat and Munch the bunny.
It's been a while since I posted a progress update (or really any blog post, ahem), but porting Firefox/Fennec to Android is progressing at a good clip. After working out a few kinks (and setting the all-important "you're allowed to touch the network" permission), I just got our first page load:
Mouse events sort of work, toplevel windows sort of work, keyboard doesn't work yet but shouldn't be hard to hook up. This is running in an emulator at the moment for ease of debugging, but it's working just fine on physical hardware as well.
You'll note that this is the full Firefox interface, and not the Fennec/Firefox Mobile UI; we're testing with the full interface because it's significantly more complex than the mobile UI and stresses Gecko much more. So, if the full UI works, then Fennec should work fine as well. Given the interest in Android on netbook and tablet devices, an updated version of the full Firefox UI might find a home on some of these. Android has been pretty great to work with so far; it's a bit unusual platform for us due to its Java core, but with the NDK we're able to bridge things together without many problems.
We're still a ways to go before any kind of usable alpha release, but we're certainly one step closer. We'll also be able to accelerate our progress now that we have some of the basic scaffolding in place. I know I'm looking forward to running Fennec on my Droid, and there are tons of Android devices coming out that should be great platforms for Fennec.
The Mozilla Store needs your help! If you have a minute, please take this quick survey
This is the second in a series of blog posts (previous) on how Mozilla is using its trademarks to try and make sure everyone gets a genuine copy of our software, for free. I will continue to use Germany as an example.
When we discover a wilful trademark infringement, we normally take the following steps, in increasing order of seriousness:
We have a good relationship with the major search engines, and being delisted or having their advertising removed does a great deal to "cut off the air supply" of fraudulent sites.
In most cases, sending a C&D; sorts out the problem. If it doesn't, we:
Where there is a domain name involved which infringes Mozillaâs trademarks, we can file a domain dispute alongside sending the C&D.; For German domains, this is very quick and cost-efficient (national stereotypes at work :-). Upon cancellation of a .de domain by the infringer, DENIC automatically transfers the domain to Mozilla. (For other TLDs, it's not so automatic.)
We have already obtained numerous domain names this way. Examples include "mozilla.de", "mozilla-europe.de", "mozillamessaging.de" and "mozilla.fr", as well as dozens of typosquatted domains.
Unfortunately, for subscription traps, a C&D; rarely has any effect. So we move on to:
In Germany, PIs are also quick and cheap. Typically, it takes 1 or 2 days to obtain a PI. The proceedings are ex-parte (you only need one side in court), the other side is not even notified of the application for a PI and there is no discovery of evidence. You make your case, and the judge decides.
PIs become effective upon service. If they are not complied with, they can be enforced through penalty payment proceedings. However, a quicker way to take the site down is by approaching the provider. Under German law, internet providers are liable for infringing content once they are made aware of the infringement. Thus, a letter to a provider, accompanied by a copy of the PI, usually leads to the immediate shutdown of the site. (Remember, the site has already been warned of proceedings by the C&D; this is not coming out of the blue.)
So far, Mozilla has needed to file 6 7 (another one this week) PIs, and all of them were successful. In two cases, the other side appealed, but the PI was confirmed on appeal.
I've just finished watching Diederik van Liere's fascinating presentation (Ogg video, 20 mins), linked to by Mark, about his work with bugzilla.mozilla.org data. Download the full slide deck - you'll need it to follow along with my comments, which should be of interest to the community-minded.
Slides 9 and 10, the community dynamics slides, are worrying. Diederik explains the decline in the size of the community as "increased product maturity", but I'm not sure that's true. If it were, we would expect to see the number of people entering the community decreasing. However, that number has stayed roughly constant, with peaks surrounding a release as we reach out to beta testers, and as new users report bugs. It's the number of people leaving which seems to be increasing. Fewer people are hanging around once they get here. And I don't know why.
Slide 11, about what the final resolutions ended up being of bugs filed in each year, is fascinating. It would be really interesting to see that graphed at a greater granularity.
We have made significant progress in reducing the percentage of duplicate bugs filed. People complain about Bugzilla's search, but the percentage was a flat 25% from 2002-2004, and it's now a flat 13% - basically half what it was. Also, from a low of 34% of bugs filed being FIXED, we are now up at 56%.
There are no doubt lots of factors involved in this effect, including the reduction in the size of the community mentioned in the earlier slides. I'm really interested in working out what we might have done which has improved the situation. I have an utterly open mind on this. here are some significant events I can think of which may be relevant:
Can anyone else think of other events or software deployments which may be relevant? I'm happy to do the research to find out when they happened.
In the past week, I landed a few performance improvements to code for SVG's foreignObject element. (To be exact, I fixed bug 403443, bug 418063, and bug 541188.) This was a small side project that resulted from trying to use foreignObject for my inverted tinderbox display and realizing that foreignObject (which was what I initially tried) was significantly slower than using SVG filters in HTML (which also turned out to be simpler). These improvements are all available in today's nightly builds.
In particular, when we need to repaint a small part of the contents of a foreignObject (for example, due to typing in a text field or hovering over a link), we now repaint only the part that we need to (just like we do when not inside a foreignObject), rather than repainting the whole foreignObject.
This is quite noticeable when interacting with pages, for example when moving the mouse over links or when selecting text in Mark Finkle's example (from his blog) or in Paul Rouget's demo (especially if you load http://www.mozilla.com/ and then hover over the menus at the top of the page).
The awesome Jeremy Orem has written a Mediawiki extension to allow the direct embedding of Open Video, and has turned this feature on on wiki.mozilla.org. Check out my demo page (you just type the normal HTML syntax into the wiki markup) and then feel free to use it to host Mozilla-relevant videos. (Note: wiki.mozilla.org has a 32MB file upload limit.)
In a follow-up to my previous post, here's an example of what can happen if your build your business on non-free data or software from a single supplier:
Nav4All navigation shut down by NavteqLetter to 27,625,631 Nav4All navigation customers
Dear Customers,
It is with the deepest regret that we hereby notify you that the global navigation of Nav4All and the Tracking & Tracing will go offline in 3 days. The reason for the same is that the data licence agreement with Navteq (a 100% Nokia subsidiary) was not extended, in a totally unexpected manner. ...
Nav4All worked on "hundreds of different mobile telephones of many makes such as Blackberry, Sony Ericsson, Samsung, Motorola, Android, HTC, Nokia, LG, Iphone, Ipod etc." Navteq is now owned by Nokia. It's not hard to join the dots. I'm somewhat surprised Nav4All call this "totally unexpected", though. It's the obvious thing for Nokia to do. And they bought Navteq over two years ago. If I were a Nav4All shareholder, I'd be having strong words with the management right now...
Software freedom means never having to say "I'm very much hoping Apple continues to allow...".
And that's all you'll hear from me about the iPad :-)