Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 262333 - A backup/restore mechanism is required during install
Summary: A backup/restore mechanism is required during install
Status: RESOLVED FIXED
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: p2 (show other bugs)
Version: 3.5   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.5 M7   Edit
Assignee: John Arthorne CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 220647 262336 262337 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-01-25 22:13 EST by Henrik Lindberg CLA
Modified: 2009-04-20 18:05 EDT (History)
5 users (show)

See Also:


Attachments
Implementation of BackupStore - see Comment (108.46 KB, patch)
2009-01-29 16:33 EST, Henrik Lindberg CLA
no flags Details | Diff
With RemoveAction and correct copyright text (115.60 KB, patch)
2009-01-29 17:34 EST, Henrik Lindberg CLA
no flags Details | Diff
Forgot to add RemoveAction extension point (115.98 KB, patch)
2009-01-29 21:10 EST, Henrik Lindberg CLA
no flags Details | Diff
Failed tests on Windows (27.49 KB, text/plain)
2009-02-04 11:59 EST, Matthew Piggott CLA
no flags Details
BackupStore.java (28.45 KB, text/plain)
2009-02-04 13:25 EST, Henrik Lindberg CLA
no flags Details
Updated failed tests (32.66 KB, text/plain)
2009-02-04 17:50 EST, Matthew Piggott CLA
no flags Details
BackupStore.java (28.84 KB, text/plain)
2009-02-05 12:01 EST, Henrik Lindberg CLA
no flags Details
BackupTest.java - fixed issue (7.48 KB, text/plain)
2009-02-05 12:04 EST, Henrik Lindberg CLA
no flags Details
patch of native touchpoint tests (22.31 KB, patch)
2009-02-05 12:14 EST, Henrik Lindberg CLA
no flags Details | Diff
Updated patch with tests (118.06 KB, text/plain)
2009-02-20 12:07 EST, John Arthorne CLA
no flags Details
Updated patch - fixed cases where listFiles can return null (115.80 KB, patch)
2009-02-20 19:02 EST, Henrik Lindberg CLA
no flags Details | Diff
New impl (and modified tests) that does not use volume roots (115.76 KB, patch)
2009-02-23 17:38 EST, Henrik Lindberg CLA
john.arthorne: iplog+
Details | Diff
Additional fix (1.07 KB, patch)
2009-04-02 15:45 EDT, John Arthorne CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Henrik Lindberg CLA 2009-01-25 22:13:17 EST
When running an installation the native actions performs unzip, cleanupzip and ln in a way that if the transaction rolls back, there is risk that old files are lost and a the new installation is trashed.

To overcome this problem, there should be a mechanism to move files out of harms way and later restore them if needed.

I have almost finished such an implementation and will submit it as a patch.

The idea is that instead of simply deleting files the file is given to a BackupStore for safekeeping. When rolling back, actions should still undo their stuff, but can rely on BackupStore to restore all files and directories that were "deleted". If the operation succeeds, the BackupStore is asked to cleanup the backup copy.

My first implementation will not support checkpointing - but that should be easy to add. It does however tries it best to create unique backup folders across the same VM, across multiple VMs on same box, and across boxes (since provisioning may take place concurrently in remote file systems). Most provisioning tasks are probably just touching files within one install location (paired with a locked profile) - but there are occasions where files outside of this directory needs to be backed up during provisioning - hence the more elaborate handling of uniqueness. 

Once finished, I will modify the CopyAction, and CleanucopyActions submitted as patches earlier to use the backup mechanism. Will supply JUnit test as well.
Comment 1 Henrik Lindberg CLA 2009-01-25 22:32:36 EST
My idea is to make use of the touchpoint rollback() (to restore files), and commit() (to cleaout the backups).
Comment 2 Henrik Lindberg CLA 2009-01-29 16:33:08 EST
Created attachment 124206 [details]
Implementation of BackupStore - see Comment

Patch contains:
- Implementation of BackupStore (in o.e.e.p2.core.helpers
- CopyAction, CleanupcopyAction
- NativeTouchpoint use of BackupStore
- FileUtils in o.e.e.p2.core.helpers use BackupStore when unzipping
- Use of backup in Unzip, Cleanupzip, Rmdir, Mkdir, and Link actions
Comment 3 Henrik Lindberg CLA 2009-01-29 17:34:04 EST
Created attachment 124216 [details]
With RemoveAction and correct copyright text

This replacement attachment Includes a RemoveAction as well (with JUnit test), and added missing copyright text on some classes.
Comment 4 Henrik Lindberg CLA 2009-01-29 21:10:18 EST
Created attachment 124233 [details]
Forgot to add RemoveAction extension point

I was a bit too fast when adding the RemoveAction - forgot to also add an extension for it. Included in this patch.
Comment 5 Henrik Lindberg CLA 2009-02-03 20:38:26 EST
In the last p2 call, someone said there were some questions about the unique id generation...
Comment 6 Matthew Piggott CLA 2009-02-04 11:59:00 EST
Created attachment 124694 [details]
Failed tests on Windows

I've taken a look at the code for BackupStore & ran the test cases on Windows, but had a few problems.

A the moment 7 of the 18 tests fail, I believe indirectly caused by the location of the backup directory.  The tests are creating directories in the root of C, but are not removing them (File.remove() isn't noticing that it isn't deleting any directory in the tree).  Creating/deleting directories in the root would be problematic in Vista as users need Administrator access for those changes, so would fail, or present UAC pop-ups requesting permission.  A similar issue might occur on a *nix system if the backup directory were to resolve to /.  Simon recently added a File object with the key "profileDataDirectory" to the parameter Map, perhaps that could be used as the location for backups.  

I also wondered about backupCopy, to me logically it makes sense to leave the original file in place and create the backup, rather than move the original, and attempt to recreate it.  If an IOException were to occur, the user would need to manually restore the original file.  Perhaps FileUtils.copy() should used?
Comment 7 Henrik Lindberg CLA 2009-02-04 12:33:59 EST
(In reply to comment #6)
> Created an attachment (id=124694) [details]
> Failed tests on Windows
> 
> I've taken a look at the code for BackupStore & ran the test cases on Windows,
> but had a few problems.
> 
> A the moment 7 of the 18 tests fail, I believe indirectly caused by the
> location of the backup directory.  The tests are creating directories in the
> root of C, but are not removing them (File.remove() isn't noticing that it
> isn't deleting any directory in the tree).  Creating/deleting directories in
> the root would be problematic in Vista as users need Administrator access for
> those changes, so would fail, or present UAC pop-ups requesting permission.  A
> similar issue might occur on a *nix system if the backup directory were to
> resolve to /.  Simon recently added a File object with the key
> "profileDataDirectory" to the parameter Map, perhaps that could be used as the
> location for backups.  
> 
The problem is that a useful root per filesystem is needed - there is no way to figure out what type of file system the backup file is stored on.
The current implementation assumes that if you are allowed to create a file in a directory, you are also allowed to create (and subsequently delete) a directory there. Maybe the cure is to create and delete a directory instead in the probing logic. 

Do you think that technique would work on Windows? 

> I also wondered about backupCopy, to me logically it makes sense to leave the
> original file in place and create the backup, rather than move the original,
> and attempt to recreate it.  If an IOException were to occur, the user would
> need to manually restore the original file.  Perhaps FileUtils.copy() should
> used?

The normal case is that the file is going to be deleted, so always copying wastes resources. (Although if a copy was made, the backup location could be anywhere on disk).  By moving the file (instead of copying) the issue of permissions and special files is also worked around. Say that the original is a link, or something with special permissions. The user would expect the exact thing after a rollback. It would not be possible to recreate such special files from within java.


Comment 8 Henrik Lindberg CLA 2009-02-04 13:25:59 EST
Created attachment 124710 [details]
BackupStore.java

Please try with the attached BackupStore.java - the probing now also checks if it is possible to create and delete a directory in the directory elected to be root. Hopefully this is enough to make it work on Windows and Vista.
Comment 9 Matthew Piggott CLA 2009-02-04 17:50:22 EST
Created attachment 124735 [details]
Updated failed tests

The new changes are causing failures in the BackupStore tests on Windows XP as well.  It is also still creating directories in C:\
Comment 10 Henrik Lindberg CLA 2009-02-04 22:29:05 EST
I brushed of the dust on my old XP box, and started debugging. I have a suspicion that it is the backupCopy that creates the problem. I think that somehow, windows thinks the files are "in use" and refuses to rename.  The problem seems to be time sensitive - slowly stepping through the code made the code work. Have a strong suspicion this has to do with file handles not being released to windows...

Anyone with similar experiences of rename? 
Comment 11 Thomas Hallgren CLA 2009-02-05 02:00:00 EST
Any chance a FileOutputStream, FileInputStream, JarFile etc. is left dangling somewhere and finally closed during GC?
Comment 12 Pascal Rapicault CLA 2009-02-05 06:10:43 EST
I understand the rationale behind writing in a common parent folder, however somehow this is raising the red flag for me. Could not the backup store be rooted in the same folder where the writing? This would result in several stores but is this a real issue?

> Maybe the cure is to create and delete a directory instead in the probing logic.
  This is what we are doing to properly determine in equinox or the launcher the write capability of a folder
Comment 13 Henrik Lindberg CLA 2009-02-05 07:32:06 EST
(In reply to comment #12)
> I understand the rationale behind writing in a common parent folder, however
> somehow this is raising the red flag for me. Could not the backup store be
> rooted in the same folder where the writing? This would result in several
> stores but is this a real issue?
> 
I started that way, but it gets quite complicated as the folder where the backup folder is placed could also be backed up. 

> > Maybe the cure is to create and delete a directory instead in the probing logic.
>   This is what we are doing to properly determine in equinox or the launcher
> the write capability of a folder
> 
Good to know. I am using this method now to detect directory writability.

After long debugging session on a Windows XP, I now know that this has nothing to do with finding a writable directory. It is related to copying - I am writing a smaller test to provoke the problem.


Comment 14 Henrik Lindberg CLA 2009-02-05 11:29:12 EST
I found the issue - it is an error in the test code where the file content assertion leaves the file open! 

New version of the test class will be uploaded shortly.
Comment 15 Henrik Lindberg CLA 2009-02-05 12:01:13 EST
Created attachment 124825 [details]
BackupStore.java

Minor change in BackupStore.java - should not be required to make the tests run on Windows compared to previous attachment of this class.
Comment 16 Henrik Lindberg CLA 2009-02-05 12:04:27 EST
Created attachment 124826 [details]
BackupTest.java - fixed issue

This BackupStore.java should pass the tests on Windows as well.
The issue was that the assertion logic that checked the content of a file did not close the file after reading, And on Windows it is then impossible to move or delete the file.
Comment 17 Henrik Lindberg CLA 2009-02-05 12:14:20 EST
Created attachment 124827 [details]
patch of native touchpoint tests

This patch fixes the same problem as in BackupTest - but for the native touchpoint action tests that makes use of Backup. (Same problem - the file content assertion left the file open).

Would very much appreciate if someone could run the tests on Vista as well.
Comment 18 Pascal Rapicault CLA 2009-02-11 20:30:26 EST
Reassigning to John for review and setting M6 as a goal
Comment 19 John Arthorne CLA 2009-02-17 15:23:17 EST
I have entered a CQ for this contribution:

https://dev.eclipse.org/ipzilla/show_bug.cgi?id=3105
Comment 20 John Arthorne CLA 2009-02-17 16:10:14 EST
One high level question I have is why is this IBackupStore in p2.core? It feels like utility classes for use only by touchpoints. Unless we have an immediate need for it elsewhere, org.eclipse.equinox.p2.engine feels like a better home for it.
Comment 21 Henrik Lindberg CLA 2009-02-17 18:24:28 EST
(In reply to comment #20)
> One high level question I have is why is this IBackupStore in p2.core? It feels
> like utility classes for use only by touchpoints. Unless we have an immediate
> need for it elsewhere, org.eclipse.equinox.p2.engine feels like a better home
> for it.
> 
I placed the backup store there because it was needed in one of the other helpers (in core) that performs unzipping. That was the only reason.
Comment 22 John Arthorne CLA 2009-02-20 12:07:37 EST
Created attachment 126320 [details]
Updated patch with tests

I was still having test failures on Windows due to a file being left open. I finally tracked this down to the assertFileContents methods in the tests that didn't close the reader. While tracking it down I found and fixed some other places where streams weren't being closed properly in finally blocks.

This patch also moves the backup store out of p2.core and into p2.touchpoint.natives, which is the only user of it. We can consider moving it elsewhere later if needed, but this avoids adding the new code dependency where it isn't needed.
Comment 23 John Arthorne CLA 2009-02-20 12:15:16 EST
Some other outstanding issues:

 - File.renameTo is used. This method doesn't support renaming across volumes (as mentioned in the javadoc). We need to fall back to a copy+delete when renameTo fails.
 - File.listFiles can return null, but this isn't consistently checked (CleanupCopyAction, CopyAction, BackupStore#fullyDelete, BackupStore#restore).
Comment 24 Henrik Lindberg CLA 2009-02-20 12:22:54 EST
(In reply to comment #23)
> Some other outstanding issues:
> 
>  - File.renameTo is used. This method doesn't support renaming across volumes
> (as mentioned in the javadoc). We need to fall back to a copy+delete when
> renameTo fails.
>  - File.listFiles can return null, but this isn't consistently checked
> (CleanupCopyAction, CopyAction, BackupStore#fullyDelete, BackupStore#restore).
> 

The solution takes that into account. It never moves across volume boundaries. It starts by finding the volume boundaries. 
ok, the second issue should be handled. 

Comment 25 Henrik Lindberg CLA 2009-02-20 12:27:00 EST
(In reply to comment #22)
> Created an attachment (id=126320) [details]
> Updated patch with tests
> 
> I was still having test failures on Windows due to a file being left open. I
> finally tracked this down to the assertFileContents methods in the tests that
> didn't close the reader. While tracking it down I found and fixed some other
> places where streams weren't being closed properly in finally blocks.
> 
ok, thanks, I thought I had all of those fixed in the additional attachments. 

> This patch also moves the backup store out of p2.core and into
> p2.touchpoint.natives, which is the only user of it. We can consider moving it
> elsewhere later if needed, but this avoids adding the new code dependency where
> it isn't needed.
> 
 
How did you deal with the fact that file utils that performs the unzip needs to support the backup store?
Comment 26 Henrik Lindberg CLA 2009-02-20 12:28:06 EST
(In reply to comment #23)
> Some other outstanding issues:
> 
>  - File.listFiles can return null, but this isn't consistently checked
> (CleanupCopyAction, CopyAction, BackupStore#fullyDelete, BackupStore#restore).
> 
So, should I patch your latest patch to fix these?

Comment 27 John Arthorne CLA 2009-02-20 15:57:30 EST
Yes, please start from my patch and update from there.
Comment 28 Henrik Lindberg CLA 2009-02-20 16:53:51 EST
*** Bug 220647 has been marked as a duplicate of this bug. ***
Comment 29 Henrik Lindberg CLA 2009-02-20 18:54:34 EST
I have fixed the handling of listFiles possibly returning null on IO Errors. New patch to follow.

What I wonder about is the earlier suggestion to do a copy if the move fails. The move will not fail because of moving between volumes as the backup directory is always placed on the same volume as the file being backed up. So that leaves moves that are blocked by other reasons ("in use", "locking", "permissions" etc). I wonder if it is not better to fail immediately in these cases as it is unlikely that a delete of the files will work anyway, and later, a restore would most likely also fail. So - I suggest that the current behavior is kept (i.e. no copy if move fails). Under what circumstances do you think it is valuable to make a copy if move fails (other than volume boundaries - which is already handled)?

Comment 30 Henrik Lindberg CLA 2009-02-20 19:02:44 EST
Created attachment 126371 [details]
Updated patch - fixed cases where listFiles can return null

Patch contains implementation and tests.
Comment 31 John Arthorne CLA 2009-02-22 23:32:02 EST
I think we need to support the case where the backup store isn't on the same volume as the files being backed up. We have code elsewhere in Eclipse for doing recursive move without renameTo, so there is no need for us to have this limitation (apart from performance). I don't know how this current code behaves on *nix, but on Windows it currently stores files at the root of the drive (C:\). This isn't a reasonable place for an application to be spreading its files. Windows has guidelines on where applications can write their date (under Documents and Settings, either the temp dir or user's home dir).

I suggest we should keep BackupStore simple and require clients of BackupStore to provide the root directory for the backup store. Our usage in the engine and touchpoints can use the engine's profile data area (eclipse/p2/org.eclipse.p2.engine/profileRegistry/<profileId>/.data). We know the p2 location is writeable and under our control, and we have a story on Vista and elsewhere for ensuring this directory is writeable.
Comment 32 Henrik Lindberg CLA 2009-02-23 12:53:44 EST
(In reply to comment #31)
> I think we need to support the case where the backup store isn't on the same
> volume as the files being backed up. We have code elsewhere in Eclipse for
> doing recursive move without renameTo, so there is no need for us to have this
> limitation (apart from performance). I don't know how this current code behaves
> on *nix, but on Windows it currently stores files at the root of the drive
> (C:\). This isn't a reasonable place for an application to be spreading its
> files. Windows has guidelines on where applications can write their date (under
> Documents and Settings, either the temp dir or user's home dir).
> 
The current impl finds the highest writeable directory on a volume and places the
backup directory there. Works on n*x and windows.

> I suggest we should keep BackupStore simple and require clients of BackupStore
> to provide the root directory for the backup store. Our usage in the engine and
> touchpoints can use the engine's profile data area
> (eclipse/p2/org.eclipse.p2.engine/profileRegistry/<profileId>/.data). We know
> the p2 location is writeable and under our control, and we have a story on
> Vista and elsewhere for ensuring this directory is writeable.
> 

ok, I can change the impl so it moves files if it can, and otherwise makes a copy.
The user can specify the directory where the backup directory should be stored.
It gets a bit messier as the backup needs to understand things like Windows drive names and network mapped folders. But I found a simple solution.  Working on the modified implementation now.
Comment 33 John Arthorne CLA 2009-02-23 17:05:28 EST
> The current impl finds the highest writeable directory on a volume and places
> the backup directory there. Works on n*x and windows.

I understand that it works at a technical level, but I think it doesn't match expected behaviour of applications on *nix or Windows. As a user if I found these extra files lying around at the root of my filesystem, I would be tempted to delete them. If I had multiple Eclipse-based applications installed on a volume, it would quickly create a lot of clutter. There are widely followed conventions on where application should store their state, such as:

http://www.pathname.com/fhs/pub/fhs-2.3.html
http://msdn.microsoft.com/en-us/library/bb530410.aspx#vistauac_topic6c

We have often run into these problems in the past of people complaining Eclipse is storing state where it shouldn't, so we try be well-behaved in storing our state.
Comment 34 Henrik Lindberg CLA 2009-02-23 17:38:01 EST
Created attachment 126505 [details]
New impl (and modified tests) that does not use volume roots

Here is a new implementation that does not try to find volume roots. Instead it will try a renameTo, and if that does not work, it will copy the file.

It is now also possible to instantiate the BackupStore with a directory of choice. The default is to use user.home. 

Please test on Vista. A simple way to test that cross volume backup works is to modify the BackupStoreTest class in #setUp() and have it use a directory on a different drive for the files being backed up. It is difficult to write automated testcode for this as it is unknown what drives/volumes are available in the test environment.
Comment 35 John Arthorne CLA 2009-03-02 14:34:11 EST
Moving to early M7. We are focused this week on polishing up other work for M6, and I don't think we have time to shake out any possible bugs in this. There is no impact on API or visible end user function so it's an ideal item to move into M7.

Note the CQ mentioned in comment #19 has been approved, so we should be able to get this in quickly after M6 is done.
Comment 36 Henrik Lindberg CLA 2009-03-02 15:51:38 EST
Well, the patch contains the Copy action that we would like to start using. Other than that - understand there are other issues that needs to be ironed out - getting this into m6 would be appreciated. If issues are found - I have time to work on fixing them.
Comment 37 Henrik Lindberg CLA 2009-03-18 15:01:58 EDT
Can this get in now?
Comment 38 Henrik Lindberg CLA 2009-04-01 15:31:42 EDT
Any issues with getting this comitted?
Comment 39 John Arthorne CLA 2009-04-02 10:32:16 EDT
Aiming to release this week. I did a quick check and there are two conflicts on the patch: the Util and CleanupzipAction in p2.touchpoint.natives. If you could provide an updated patch against HEAD it would speed up the process.
Comment 40 John Arthorne CLA 2009-04-02 13:49:59 EDT
Ignore the previous comment - I think I've got it merged with latest from HEAD. Just running some tests.
Comment 41 John Arthorne CLA 2009-04-02 14:45:29 EDT
Released to HEAD. The only significant change I made was to use java.io.tmpdir rather than user.home as the backup store location. This is the directory we use for all other temp files in p2 (signature files, temp folder for pack/unpack, etc). I also changed the backup folder prefix to be the profile ID, to help identify what backup folder is associated with what profile.


I ran some further manual tests:

 - installing/uninstalling from legacy site (eclemma)
 - upgrading/reverting the Eclipse SDK (between I20090331 and I20090401)

Comment 42 John Arthorne CLA 2009-04-02 15:45:58 EDT
Created attachment 130754 [details]
Additional fix

The tests were all passing, but after releaesing to HEAD they started failing. This is because the added "CVS" directories revealed a bug in the undo copy code. It was deleting directories from the top-down, which will fail when there are nested directories because you can't delete a directory with existing children. This patch flips the directory list around before deleting. The tests pass again with this fix. Henrik, can you think of any other places where we might have this problem?
Comment 43 John Arthorne CLA 2009-04-02 15:46:41 EDT
I have released this additional fix to HEAD.
Comment 44 Henrik Lindberg CLA 2009-04-02 16:22:01 EDT
(In reply to comment #43)
> I have released this additional fix to HEAD.
> 

Thanks John, I will update the wiki page that describes touchpoint actions.
Comment 45 Henrik Lindberg CLA 2009-04-02 18:09:06 EDT
(In reply to comment #41)
> Released to HEAD. The only significant change I made was to use java.io.tmpdir
> rather than user.home as the backup store location. This is the directory we
> use for all other temp files in p2 (signature files, temp folder for
> pack/unpack, etc). I also changed the backup folder prefix to be the profile
> ID, to help identify what backup folder is associated with what profile.

The only possible downside is that if the machine crashes during install, the backup will be deleted if java.io.tmpdir points to a filesystem that is cleared on boot (or is in memory). That was the reason I used users home directory. 

The delete in wrong order was an oversight, and I will review if the same mistake was made elsewhere.

Comment 46 John Arthorne CLA 2009-04-03 00:41:38 EDT
>The only possible downside is that if the machine crashes during install, the
>backup will be deleted if java.io.tmpdir points to a filesystem that is cleared
>on boot (or is in memory)

Simon correct me if I'm wrong, but I don't think the engine currently supports rollback across machine restarts. I.e., if you crash in the middle of an install, I don't think the rollback will happen in the next session.
Comment 47 Henrik Lindberg CLA 2009-04-03 07:49:58 EDT
(In reply to comment #46)
> >The only possible downside is that if the machine crashes during install, the
> >backup will be deleted if java.io.tmpdir points to a filesystem that is cleared
> >on boot (or is in memory)
> 
> Simon correct me if I'm wrong, but I don't think the engine currently supports
> rollback across machine restarts. I.e., if you crash in the middle of an
> install, I don't think the rollback will happen in the next session.
> 
Neither does the backup solution for native,,, but a manual restore is possible. And would make it possible to detect a previous crash and offer recover if the backup was kept.

For now it is fine to keep the backup in temp, and if "recover on restart" is ever implemented, it would be very easy to move the backups to a place that survives a machine reboot.
Comment 48 Simon Kaegi CLA 2009-04-03 09:09:28 EDT
(In reply to comment #46)
> Simon correct me if I'm wrong, but I don't think the engine currently supports
> rollback across machine restarts. I.e., if you crash in the middle of an
> install, I don't think the rollback will happen in the next session.

Someday... but not for this release.
Comment 49 Henrik Lindberg CLA 2009-04-03 10:09:22 EDT
(In reply to comment #48)
> (In reply to comment #46)
> > Simon correct me if I'm wrong, but I don't think the engine currently supports
> > rollback across machine restarts. I.e., if you crash in the middle of an
> > install, I don't think the rollback will happen in the next session.
> 
> Someday... but not for this release.
> 
Should we perhaps create an issue to keep track of this future enhancement?
Comment 50 Henrik Lindberg CLA 2009-04-13 09:03:35 EDT
*** Bug 262337 has been marked as a duplicate of this bug. ***
Comment 51 Henrik Lindberg CLA 2009-04-20 18:05:36 EDT
*** Bug 262336 has been marked as a duplicate of this bug. ***