 math.parser generic ;
 IN: bootstrap.stage2
 
+SYMBOL: bootstrap-time
+
+: default-image-name ( -- string )
+    vm file-name windows? [ "." split1 drop ] when
+    ".image" append ;
+
+: do-crossref ( -- )
+    "Cross-referencing..." print flush
+    H{ } clone crossref set-global
+    xref-words
+    xref-generics
+    xref-sources ;
+
+: load-components ( -- )
+    "exclude" "include"
+    [ get-global " " split [ empty? not ] subset ] 2apply
+    seq-diff
+    [ "bootstrap." swap append require ] each ;
+
+: compile-remaining ( -- )
+    "Compiling remaining words..." print flush
+    vocabs [
+        words "compile" "compiler" lookup execute
+    ] each ;
+
+: count-words ( pred -- )
+    all-words swap subset length number>string write ;
+
+: print-report ( time -- )
+    1000 /i
+    60 /mod swap
+    "Bootstrap completed in " write number>string write
+    " minutes and " write number>string write " seconds." print
+
+    [ compiled? ] count-words " compiled words" print
+    [ symbol? ] count-words " symbol words" print
+    [ ] count-words " words total" print
+
+    "Bootstrapping is complete." print
+    "Now, you can run Factor:" print
+    vm write " -i=" write "output-image" get print flush ;
+
 ! Wrap everything in a catch which starts a listener so
 ! you can see what went wrong, instead of dealing with a
 ! fep
 [
-    vm file-name windows? [ "." split1 drop ] when
-    ".image" append "output-image" set-global
+    ! We time bootstrap
+    millis >r
+
+    default-image-name "output-image" set-global
 
     "math help compiler tools ui ui.tools io" "include" set-global
     "" "exclude" set-global
 
     parse-command-line
 
-    "-no-crossref" cli-args member? [
-        "Cross-referencing..." print flush
-        H{ } clone crossref set-global
-        xref-words
-        xref-generics
-        xref-sources
-    ] unless
+    "-no-crossref" cli-args member? [ do-crossref ] unless
 
     ! Set dll paths
     wince? [ "windows.ce" require ] when

    ] if

    [
        "exclude" "include"
        [ get-global " " split [ empty? not ] subset ] 2apply
        seq-diff
        [ "bootstrap." swap append require ] each

        run-bootstrap-init

        "Compiling remaining words..." print flush

        "bootstrap.compiler" vocab [
            vocabs [
                words "compile" "compiler" lookup execute
            ] each
        ] when
    ] with-compiler-errors
    :errors

            ] [ print-error 1 exit ] recover
        ] set-boot-quot

        millis r> - dup bootstrap-time set-global
        print-report

        "output-image" get resource-path save-image-and-exit
    ] if
