Index: vss2svn.pl
===================================================================
--- vss2svn.pl	(revision 340)
+++ vss2svn.pl	(working copy)
@@ -1067,7 +1067,42 @@
 
     my($sth, $row, $action, $handler, $physinfo, $itempaths, $allitempaths);
 
-    my $sql = 'SELECT * FROM PhysicalAction ORDER BY timestamp ASC, '
+    # Will find all restore sources because they should be created before
+    # someone will access it. Else some elements will be lost
+    my $sql = 'SELECT physname, parentphys, itemname FROM PhysicalAction '
+            . 'WHERE actiontype = "RESTOREDPROJECT" AND itemname LIKE "%/"';
+
+    $sth = $gCfg{dbh}->prepare($sql);
+    $sth->execute();
+
+    my $physrestore;
+    my $physrestorename;
+    my $physrestoresrcname; # root name where to restore
+    while(defined($row = $sth->fetchrow_hashref() )) {
+        $physrestore->{$row->{physname}} = 'FALSE';
+        $physrestorename->{$row->{physname}} = $row->{itemname};
+# TODO: We should create human readable but unique folder name names
+#        $physrestoresrcname->{$row->{physname}} = $row->{parentphys}."_".$row->{itemname};
+        $physrestoresrcname->{$row->{physname}} = $row->{itemname};
+    }
+
+    # It is required that root will be added first.
+    # Otherwise it will not be possible to add items to restored projects
+    # if project was created before root. We will do such by patching
+    # root time
+    
+    $sql = 'UPDATE PhysicalAction '
+            . 'SET timestamp = (SELECT MIN(timestamp)-1 FROM PhysicalAction) '
+            . 'WHERE '
+            .   'physname = "AAAAAAAA" AND '
+            .   'parentphys = "" AND '
+            .   'actiontype = "ADD" AND '
+            .   'itemname = "/" '
+            ;
+    $sth = $gCfg{dbh}->prepare($sql);
+    $sth->execute();
+
+    $sql = 'SELECT * FROM PhysicalAction ORDER BY timestamp ASC, '
             . 'itemtype ASC, priority ASC, parentdata ASC, sortkey ASC, action_id ASC';
 
     $sth = $gCfg{dbh}->prepare($sql);
@@ -1094,6 +1129,55 @@
         $row->{author} = Encode::decode_utf8( $row->{author} );
         $row->{label} = Encode::decode_utf8( $row->{label} );
 
+        my $parentphys = $row->{parentphys};
+        if (defined $parentphys && not $parentphys eq "") {
+            if (exists $physrestore->{$parentphys} && $physrestore->{$parentphys} eq 'FALSE') {
+                # Will create a fake 'external project' in DB before accessing it
+                my $ext_row;
+                %$ext_row = %$row;
+                $ext_row->{physname} = $row->{parentphys};
+                # TODO: Better to restore to special '/External' directory
+                $ext_row->{parentphys} = "AAAAAAAA";
+                $ext_row->{actiontype} = "ADD";
+                $ext_row->{itemtype} = 1;
+                $ext_row->{itemname} = "$physrestoresrcname->{$parentphys}";
+                $ext_row->{version} = 1;
+                my $ext_handler = Vss2Svn::ActionHandler->new($ext_row);
+               
+                $ext_handler->{verbose} = $gCfg{verbose};
+                $ext_handler->{trunkdir} = $gCfg{trunkdir};
+                my $ext_physinfo = $ext_handler->physinfo();
+                
+                if (!$ext_handler->handle('ADD')) {
+                    &ThrowWarning($ext_handler->{errmsg})
+                        if $ext_handler->{errmsg};
+    #                next ROW;
+                }
+                
+                $itempaths = $ext_handler->{itempaths};
+                $ext_row->{info} = $ext_handler->{info};
+        
+                $allitempaths = join("\t", @$itempaths);
+                $ext_row->{itempaths} = $allitempaths;
+        
+                $vsscache->add(@$ext_row{ qw(parentphys physname version actiontype itempaths
+                                     itemtype is_binary info) });
+                $joincache->add( $svnrevs->{revnum}, $vsscache->{pkey} );
+        
+                # Mark physname as added to DB
+                $physrestore->{$parentphys} = 'TRUE';
+            }
+        }
+        
+        # Now we'll skip restore root records to prevent them 'orphanted'
+
+        if ($action eq 'ADD' && not $parentphys) {
+            my $physname = $row->{physname};
+            if (defined $physname && exists $physrestore->{$physname}) {
+                next ROW;
+            }
+        }
+        
         # The handler's job is to keep track of physical-to-real name mappings
         # and return the full item paths corresponding to the physical item. In
         # case of a rename, it will return the old name, so we then do another
@@ -1731,7 +1815,6 @@
         DestroyedProject => {type => 1, action => 'DELETE'},
         RecoveredProject => {type => 1, action => 'RECOVER'},
         ArchiveProject => {type => 1, action => 'DELETE'},
-        RestoredProject => {type => 1, action => 'RESTORE'},
         CheckedIn => {type => 2, action => 'COMMIT'},
         CreatedFile => {type => 2, action => 'ADD'},
         AddedFile => {type => 2, action => 'ADD'},
Index: Vss2Svn/ActionHandler.pm
===================================================================
--- Vss2Svn/ActionHandler.pm	(revision 340)
+++ Vss2Svn/ActionHandler.pm	(working copy)
@@ -12,7 +12,7 @@
      BRANCH     => \&_branch_handler,
      MOVE       => \&_move_handler,
      RESTORE    => \&_restore_handler,
-     RESTOREDPROJECT    => \&_restore_handler,
+     RESTOREDPROJECT    => \&_restore_project_handler,
      DELETE     => \&_delete_handler,
      RECOVER    => \&_recover_handler,
      PIN        => \&_pin_handler,
@@ -384,6 +384,8 @@
         return 0;
     }
 
+    # oldName contains the source name
+    # row->{physname} contains target physical and target name
     # row->{info} contains the source parent
     # row->{parentphys} contains the target parent
 
@@ -476,13 +478,36 @@
          was_binary => $row->{is_binary},
     };
     
-    my $newName = $row->{info};
+    my $oldName = $row->{info};
     
     undef $row->{info};
 
-    return $self->_move_handler ($newName);
+    return $self->_move_handler ($oldName);
 }
+###############################################################################
+#  _restore_project_handler
+###############################################################################
+sub _restore_project_handler {
+    my($self) = @_;
+    my $row = $self->{row};
 
+    if (not exists $gPhysInfo{ $row->{physname}}) {
+        return $self->_add_handler();
+    }
+# TODO: Here should be a real parent, but currently we are always
+# attaching restored projects to root
+#    $row->{info} = $gPhysInfo{ $row->{physname}}->{name};
+    $row->{info} = 'AAAAAAAA';
+
+    $self->{action} = 'MOVE';
+    $row->{actiontype} = 'MOVE';
+
+    my $oldName = $gPhysInfo{ $row->{physname}}->{name};
+    $gPhysInfo{ $row->{physname}}->{name} = $row->{itemname};
+
+    return $self->_move_handler ($oldName);
+}
+
 ###############################################################################
 #  _delete_handler
 ###############################################################################
