diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm
index 6baefa545..6b932f92f 100644
--- a/lib/Slic3r/GUI/MainFrame.pm
+++ b/lib/Slic3r/GUI/MainFrame.pm
@@ -62,13 +62,14 @@ sub new {
     eval { Wx::ToolTip::SetAutoPop(32767) };
     
     # initialize status bar
-    $self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new($self, Wx::NewId);
+    $self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new();
+    # $self->{statusbar}->SetParent($self, Wx::NewId);
+    $self->{statusbar}->Embed;
     $self->{statusbar}->SetStatusText(L("Version ").$Slic3r::VERSION.L(" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases"));
-    $self->SetStatusBar($self->{statusbar});
-    
+
     # Make the global status bar and its progress indicator available in C++
     $appController->set_global_progress_indicator(
-        $self->{statusbar}->{prog}->GetId(),
+        $self->{statusbar}->GetProgId(),
         $self->{statusbar}->GetId(),
     );
 
diff --git a/lib/Slic3r/GUI/ProgressStatusBar.pm b/lib/Slic3r/GUI/ProgressStatusBar.pm
index 32fd52680..a696feb7f 100644
--- a/lib/Slic3r/GUI/ProgressStatusBar.pm
+++ b/lib/Slic3r/GUI/ProgressStatusBar.pm
@@ -4,141 +4,143 @@ package Slic3r::GUI::ProgressStatusBar;
 use strict;
 use warnings;
 
-use Wx qw(:gauge :misc);
-use base 'Wx::StatusBar';
+# use Wx qw(:gauge :misc);
+# use base 'Wx::StatusBar';
 
-sub new {
-    my $class = shift;
-    my $self = $class->SUPER::new(@_);
-    
-    $self->{busy} = 0;
-    $self->{timer} = Wx::Timer->new($self);
-    $self->{prog} = Wx::Gauge->new($self, wxGA_HORIZONTAL, 100, wxDefaultPosition, wxDefaultSize);
-    $self->{prog}->Hide;
-    $self->{cancelbutton} = Wx::Button->new($self, -1, "Cancel", wxDefaultPosition, wxDefaultSize);
-    $self->{cancelbutton}->Hide;
-    
-    $self->SetFieldsCount(3);
-    $self->SetStatusWidths(-1, 150, 155);
-    
-    Wx::Event::EVT_TIMER($self, \&OnTimer, $self->{timer});
-    Wx::Event::EVT_SIZE($self, \&OnSize);
-    Wx::Event::EVT_BUTTON($self, $self->{cancelbutton}, sub {
-        $self->{cancel_cb}->();
-        $self->{cancelbutton}->Hide;
-    });
-    
-    return $self;
-}
+our $cancel_cb;
 
-sub DESTROY {
-    my $self = shift;    
-    $self->{timer}->Stop if $self->{timer} && $self->{timer}->IsRunning;
-}
-
-sub OnSize {
-    my ($self, $event) = @_;
+# sub new {
+#     my $class = shift;
+#     my $self = $class->SUPER::new(@_);
     
-    my %fields = (
-        # 0 is reserved for status text
-        1 => $self->{cancelbutton},
-        2 => $self->{prog},
-    );
-
-    foreach (keys %fields) {
-        my $rect = $self->GetFieldRect($_);
-        my $offset = &Wx::wxGTK ? 1 : 0; # add a cosmetic 1 pixel offset on wxGTK
-        my $pos = [$rect->GetX + $offset, $rect->GetY + $offset];
-        $fields{$_}->Move($pos);
-        $fields{$_}->SetSize($rect->GetWidth - $offset, $rect->GetHeight);
-    }
-
-    $event->Skip;
-}
-
-sub OnTimer {
-    my ($self, $event) = @_;
+#     $self->{busy} = 0;
+#     $self->{timer} = Wx::Timer->new($self);
+#     $self->{prog} = Wx::Gauge->new($self, wxGA_HORIZONTAL, 100, wxDefaultPosition, wxDefaultSize);
+#     $self->{prog}->Hide;
+#     $self->{cancelbutton} = Wx::Button->new($self, -1, "Cancel", wxDefaultPosition, wxDefaultSize);
+#     $self->{cancelbutton}->Hide;
     
-    if ($self->{prog}->IsShown) {
-        $self->{timer}->Stop;
-    }
-    $self->{prog}->Pulse if $self->{_busy};
-}
+#     $self->SetFieldsCount(3);
+#     $self->SetStatusWidths(-1, 150, 155);
+    
+#     Wx::Event::EVT_TIMER($self, \&OnTimer, $self->{timer});
+#     Wx::Event::EVT_SIZE($self, \&OnSize);
+#     Wx::Event::EVT_BUTTON($self, $self->{cancelbutton}, sub {
+#         $self->{cancel_cb}->();
+#         $self->{cancelbutton}->Hide;
+#     });
+    
+#     return $self;
+# }
+
+# sub DESTROY {
+#     my $self = shift;    
+#     $self->{timer}->Stop if $self->{timer} && $self->{timer}->IsRunning;
+# }
+
+# sub OnSize {
+#     my ($self, $event) = @_;
+    
+#     my %fields = (
+#         # 0 is reserved for status text
+#         1 => $self->{cancelbutton},
+#         2 => $self->{prog},
+#     );
+
+#     foreach (keys %fields) {
+#         my $rect = $self->GetFieldRect($_);
+#         my $offset = &Wx::wxGTK ? 1 : 0; # add a cosmetic 1 pixel offset on wxGTK
+#         my $pos = [$rect->GetX + $offset, $rect->GetY + $offset];
+#         $fields{$_}->Move($pos);
+#         $fields{$_}->SetSize($rect->GetWidth - $offset, $rect->GetHeight);
+#     }
+
+#     $event->Skip;
+# }
+
+# sub OnTimer {
+#     my ($self, $event) = @_;
+    
+#     if ($self->{prog}->IsShown) {
+#         $self->{timer}->Stop;
+#     }
+#     $self->{prog}->Pulse if $self->{_busy};
+# }
 
 sub SetCancelCallback {
     my $self = shift;
     my ($cb) = @_;
-    $self->{cancel_cb} = $cb;
-    $cb ? $self->{cancelbutton}->Show : $self->{cancelbutton}->Hide;
+    $cancel_cb = $cb;
+    # $cb ? $self->{cancelbutton}->Show : $self->{cancelbutton}->Hide;
 }
 
-sub Run {
-    my $self = shift;
-    my $rate = shift || 100;
-    if (!$self->{timer}->IsRunning) {
-        $self->{timer}->Start($rate);
-    }
-}
+# sub Run {
+#     my $self = shift;
+#     my $rate = shift || 100;
+#     if (!$self->{timer}->IsRunning) {
+#         $self->{timer}->Start($rate);
+#     }
+# }
 
-sub GetProgress {
-    my $self = shift;
-    return $self->{prog}->GetValue;
-}
+# sub GetProgress {
+#     my $self = shift;
+#     return $self->{prog}->GetValue;
+# }
 
-sub SetProgress {
-    my $self = shift;
-    my ($val) = @_;
-    if (!$self->{prog}->IsShown) {
-        $self->ShowProgress(1);
-    }
-    if ($val == $self->{prog}->GetRange) {
-        $self->{prog}->SetValue(0);
-        $self->ShowProgress(0);
-    } else {
-        $self->{prog}->SetValue($val);
-    }
-}
+# sub SetProgress {
+#     my $self = shift;
+#     my ($val) = @_;
+#     if (!$self->{prog}->IsShown) {
+#         $self->ShowProgress(1);
+#     }
+#     if ($val == $self->{prog}->GetRange) {
+#         $self->{prog}->SetValue(0);
+#         $self->ShowProgress(0);
+#     } else {
+#         $self->{prog}->SetValue($val);
+#     }
+# }
 
-sub SetRange {
-    my $self = shift;
-    my ($val) = @_;
+# sub SetRange {
+#     my $self = shift;
+#     my ($val) = @_;
     
-    if ($val != $self->{prog}->GetRange) {
-        $self->{prog}->SetRange($val);
-    }
-}
+#     if ($val != $self->{prog}->GetRange) {
+#         $self->{prog}->SetRange($val);
+#     }
+# }
 
-sub ShowProgress {
-    my $self = shift;
-    my ($show) = @_;
+# sub ShowProgress {
+#     my $self = shift;
+#     my ($show) = @_;
     
-    $self->{prog}->Show($show);
-    $self->{prog}->Pulse;
-}
+#     $self->{prog}->Show($show);
+#     $self->{prog}->Pulse;
+# }
 
-sub StartBusy {
-    my $self = shift;
-    my $rate = shift || 100;
+# sub StartBusy {
+#     my $self = shift;
+#     my $rate = shift || 100;
     
-    $self->{_busy} = 1;
-    $self->ShowProgress(1);
-    if (!$self->{timer}->IsRunning) {
-        $self->{timer}->Start($rate);
-    }
-}
+#     $self->{_busy} = 1;
+#     $self->ShowProgress(1);
+#     if (!$self->{timer}->IsRunning) {
+#         $self->{timer}->Start($rate);
+#     }
+# }
 
-sub StopBusy {
-    my $self = shift;
+# sub StopBusy {
+#     my $self = shift;
     
-    $self->{timer}->Stop;
-    $self->ShowProgress(0);
-    $self->{prog}->SetValue(0);
-    $self->{_busy} = 0;
-}
+#     $self->{timer}->Stop;
+#     $self->ShowProgress(0);
+#     $self->{prog}->SetValue(0);
+#     $self->{_busy} = 0;
+# }
 
-sub IsBusy {
-    my $self = shift;
-    return $self->{_busy};
-}
+# sub IsBusy {
+#     my $self = shift;
+#     return $self->{_busy};
+# }
 
 1;
diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt
index 0ab4648eb..2ebcb2d45 100644
--- a/xs/CMakeLists.txt
+++ b/xs/CMakeLists.txt
@@ -247,6 +247,8 @@ add_library(libslic3r_gui STATIC
     ${LIBDIR}/slic3r/GUI/UpdateDialogs.hpp
     ${LIBDIR}/slic3r/GUI/FirmwareDialog.cpp
     ${LIBDIR}/slic3r/GUI/FirmwareDialog.hpp
+    ${LIBDIR}/slic3r/GUI/ProgressStatusBar.hpp
+    ${LIBDIR}/slic3r/GUI/ProgressStatusBar.cpp
     ${LIBDIR}/slic3r/Utils/Http.cpp
     ${LIBDIR}/slic3r/Utils/Http.hpp
     ${LIBDIR}/slic3r/Utils/FixModelByWin10.cpp
@@ -267,7 +269,7 @@ add_library(libslic3r_gui STATIC
     ${LIBDIR}/slic3r/Utils/Time.hpp
     ${LIBDIR}/slic3r/Utils/HexFile.cpp
     ${LIBDIR}/slic3r/Utils/HexFile.hpp
-    ${LIBDIR}/slic3r/IProgressIndicator.hpp
+    ${LIBDIR}/slic3r/ProgressIndicator.hpp
     ${LIBDIR}/slic3r/AppController.hpp
     ${LIBDIR}/slic3r/AppController.cpp
     ${LIBDIR}/slic3r/AppControllerWx.cpp
@@ -420,6 +422,7 @@ set(XS_XSP_FILES
     ${XSP_DIR}/Utils_PrintHost.xsp
     ${XSP_DIR}/Utils_PresetUpdater.xsp
     ${XSP_DIR}/AppController.xsp
+    ${XSP_DIR}/ProgressStatusBar.xsp
     ${XSP_DIR}/XS.xsp
 )
 foreach (file ${XS_XSP_FILES})
diff --git a/xs/src/perlglue.cpp b/xs/src/perlglue.cpp
index d6bd0e94c..f0c0f4f7e 100644
--- a/xs/src/perlglue.cpp
+++ b/xs/src/perlglue.cpp
@@ -63,6 +63,7 @@ REGISTER_CLASS(Preset, "GUI::Preset");
 REGISTER_CLASS(PresetCollection, "GUI::PresetCollection");
 REGISTER_CLASS(PresetBundle, "GUI::PresetBundle");
 REGISTER_CLASS(TabIface, "GUI::Tab");
+REGISTER_CLASS(ProgressStatusBar, "GUI::ProgressStatusBar");
 REGISTER_CLASS(PresetUpdater, "PresetUpdater");
 REGISTER_CLASS(AppController, "AppController");
 REGISTER_CLASS(PrintController, "PrintController");
diff --git a/xs/src/slic3r/AppController.cpp b/xs/src/slic3r/AppController.cpp
index 58858f5fc..2f1e9a148 100644
--- a/xs/src/slic3r/AppController.cpp
+++ b/xs/src/slic3r/AppController.cpp
@@ -290,26 +290,22 @@ const PrintConfig &PrintController::config() const
 
 void AppController::arrange_model()
 {
-    auto ftr = std::async(
-               supports_asynch()? std::launch::async : std::launch::deferred,
-               [this]()
-    {
-        using Coord = libnest2d::TCoord<libnest2d::PointImpl>;
+    using Coord = libnest2d::TCoord<libnest2d::PointImpl>;
 
-        unsigned count = 0;
-        for(auto obj : model_->objects) count += obj->instances.size();
+    unsigned count = 0;
+    for(auto obj : model_->objects) count += obj->instances.size();
 
-        auto pind = global_progress_indicator();
+    auto pind = global_progress_indicator();
 
-        float pmax = 1.0;
+    float pmax = 1.0;
 
-        if(pind) {
-            pmax = pind->max();
+    if(pind) {
+        pmax = pind->max();
 
-            // Set the range of the progress to the object count
-            pind->max(count);
+        // Set the range of the progress to the object count
+        pind->max(count);
 
-        }
+    }
 
         auto dist = print_ctl()->config().min_object_distance();
 
@@ -341,16 +337,38 @@ void AppController::arrange_model()
                          _(L("Exception occurred")));
         }
 
-        // Restore previous max value
-        if(pind) {
-            pind->max(pmax);
-            pind->update(0, _(L("Arranging done.")));
-        }
-    });
+    // Create the arranger config
+    auto min_obj_distance = static_cast<Coord>(dist/SCALING_FACTOR);
 
-    while( ftr.wait_for(std::chrono::milliseconds(10))
-           != std::future_status::ready) {
-        process_events();
+    auto& bedpoints = print_ctl()->config().bed_shape.values;
+    Polyline bed; bed.points.reserve(bedpoints.size());
+    for(auto& v : bedpoints)
+        bed.append(Point::new_scale(v(0), v(1)));
+
+    if(pind) pind->update(0, _(L("Arranging objects...")));
+
+    try {
+        arr::arrange(*model_,
+                     min_obj_distance,
+                     bed,
+                     arr::BOX,
+                     false, // create many piles not just one pile
+                     [pind, count](unsigned rem) {
+            if(pind)
+                pind->update(count - rem, _(L("Arranging objects...")));
+        });
+    } catch(std::exception& e) {
+        std::cerr << e.what() << std::endl;
+        report_issue(IssueType::ERR,
+                     _(L("Could not arrange model objects! "
+                     "Some geometries may be invalid.")),
+                     _(L("Exception occurred")));
+    }
+
+    // Restore previous max value
+    if(pind) {
+        pind->max(pmax);
+        pind->update(0, _(L("Arranging done.")));
     }
 }
 
diff --git a/xs/src/slic3r/AppController.hpp b/xs/src/slic3r/AppController.hpp
index e9252b50c..58681a7de 100644
--- a/xs/src/slic3r/AppController.hpp
+++ b/xs/src/slic3r/AppController.hpp
@@ -7,7 +7,7 @@
 #include <atomic>
 #include <iostream>
 
-#include "IProgressIndicator.hpp"
+#include "ProgressIndicator.hpp"
 
 namespace Slic3r {
 
@@ -33,7 +33,7 @@ class AppControllerBoilerplate {
 public:
 
     /// A Progress indicator object smart pointer
-    using ProgresIndicatorPtr = std::shared_ptr<IProgressIndicator>;
+    using ProgresIndicatorPtr = std::shared_ptr<ProgressIndicator>;
 
 private:
     class PriData;   // Some structure to store progress indication data
diff --git a/xs/src/slic3r/AppControllerWx.cpp b/xs/src/slic3r/AppControllerWx.cpp
index 4e116c7b9..64d783356 100644
--- a/xs/src/slic3r/AppControllerWx.cpp
+++ b/xs/src/slic3r/AppControllerWx.cpp
@@ -104,10 +104,10 @@ namespace  {
  * the main thread as well.
  */
 class GuiProgressIndicator:
-        public IProgressIndicator, public wxEvtHandler {
+        public ProgressIndicator, public wxEvtHandler {
 
     wxProgressDialog gauge_;
-    using Base = IProgressIndicator;
+    using Base = ProgressIndicator;
     wxString message_;
     int range_; wxString title_;
     bool is_asynch_ = false;
@@ -153,7 +153,7 @@ public:
 
     virtual void cancel() override {
         update(max(), "Abort");
-        IProgressIndicator::cancel();
+        ProgressIndicator::cancel();
     }
 
     virtual void state(float val) override {
@@ -211,10 +211,10 @@ AppControllerBoilerplate::create_progress_indicator(unsigned statenum,
 namespace {
 
 // A wrapper progress indicator class around the statusbar created in perl.
-class Wrapper: public IProgressIndicator, public wxEvtHandler {
+class Wrapper: public ProgressIndicator, public wxEvtHandler {
     wxGauge *gauge_;
     wxStatusBar *stbar_;
-    using Base = IProgressIndicator;
+    using Base = ProgressIndicator;
     std::string message_;
     AppControllerBoilerplate& ctl_;
 
@@ -223,7 +223,7 @@ class Wrapper: public IProgressIndicator, public wxEvtHandler {
     }
 
     void _state(unsigned st) {
-        if( st <= IProgressIndicator::max() ) {
+        if( st <= ProgressIndicator::max() ) {
             Base::state(st);
 
             if(!gauge_->IsShown()) showProgress(true);
@@ -266,7 +266,7 @@ public:
     virtual void max(float val) override {
         if(val > 1.0) {
             gauge_->SetRange(static_cast<int>(val));
-            IProgressIndicator::max(val);
+            ProgressIndicator::max(val);
         }
     }
 
diff --git a/xs/src/slic3r/GUI/ProgressStatusBar.cpp b/xs/src/slic3r/GUI/ProgressStatusBar.cpp
new file mode 100644
index 000000000..13ca8cd81
--- /dev/null
+++ b/xs/src/slic3r/GUI/ProgressStatusBar.cpp
@@ -0,0 +1,156 @@
+#include "ProgressStatusBar.hpp"
+
+#include <wx/timer.h>
+#include <wx/gauge.h>
+#include <wx/button.h>
+#include <wx/statusbr.h>
+#include <wx/frame.h>
+
+#include "GUI.hpp"
+
+#include <iostream>
+
+namespace Slic3r {
+
+ProgressStatusBar::ProgressStatusBar(wxWindow *parent, int id):
+    self(new wxStatusBar(parent ? parent : GUI::get_main_frame(),
+                         id == -1? wxID_ANY : id)),
+    timer_(new wxTimer(self)),
+    prog_ (new wxGauge(self,
+                       wxGA_HORIZONTAL,
+                       100,
+                       wxDefaultPosition,
+                       wxDefaultSize)),
+    cancelbutton_(new wxButton(self,
+                               -1,
+                               "Cancel",
+                               wxDefaultPosition,
+                               wxDefaultSize))
+{
+    prog_->Hide();
+    cancelbutton_->Hide();
+
+
+    self->SetFieldsCount(3);
+    int w[] = {-1, 150, 155};
+    self->SetStatusWidths(3, w);
+
+    self->Bind(wxEVT_TIMER, [this](const wxTimerEvent&) {
+        if (prog_->IsShown()) timer_->Stop();
+        if(is_busy()) prog_->Pulse();
+    });
+
+    self->Bind(wxEVT_SIZE, [this](wxSizeEvent& event){
+        wxRect rect;
+        self->GetFieldRect(1, rect);
+        auto offset = 0;
+        cancelbutton_->Move(rect.GetX() + offset, rect.GetY() + offset);
+        cancelbutton_->SetSize(rect.GetWidth() - offset, rect.GetHeight());
+
+        self->GetFieldRect(2, rect);
+        prog_->Move(rect.GetX() + offset, rect.GetY() + offset);
+        prog_->SetSize(rect.GetWidth() - offset, rect.GetHeight());
+
+        event.Skip();
+    });
+
+    cancelbutton_->Bind(wxEVT_BUTTON, [this](const wxCommandEvent&) {
+        if(cancel_cb_) cancel_cb_();
+        cancelbutton_->Hide();
+    });
+}
+
+//ProgressStatusBar::ProgressStatusBar(): ProgressStatusBar(nullptr, wxID_ANY)
+//{
+
+//}
+
+ProgressStatusBar::~ProgressStatusBar() {
+    if(timer_->IsRunning()) timer_->Stop();
+}
+
+int ProgressStatusBar::get_progress() const
+{
+    return prog_->GetValue();
+}
+
+void ProgressStatusBar::set_progress(int val)
+{
+    if(!prog_->IsShown()) show_progress(true);
+
+    if(val == prog_->GetRange()) {
+        prog_->SetValue(0);
+        show_progress(false);
+    } else {
+        prog_->SetValue(val);
+    }
+}
+
+void ProgressStatusBar::set_range(int val)
+{
+    if(val != prog_->GetRange()) {
+        prog_->SetRange(val);
+    }
+}
+
+void ProgressStatusBar::show_progress(bool show)
+{
+    prog_->Show(show);
+    prog_->Pulse();
+}
+
+void ProgressStatusBar::start_busy(int rate)
+{
+    busy_ = true;
+    show_progress(true);
+    if (!timer_->IsRunning()) {
+        timer_->Start(rate);
+    }
+}
+
+void ProgressStatusBar::stop_busy()
+{
+    timer_->Stop();
+    show_progress(false);
+    prog_->SetValue(0);
+    busy_ = false;
+}
+
+void ProgressStatusBar::set_cancel_callback(ProgressStatusBar::CancelFn ccb) {
+    cancel_cb_ = ccb;
+    if(ccb) cancelbutton_->Show();
+    else cancelbutton_->Hide();
+}
+
+void ProgressStatusBar::run(int rate)
+{
+    if(!timer_->IsRunning()) {
+        timer_->Start(rate);
+    }
+}
+
+void ProgressStatusBar::Embed()
+{
+    std::cout << "Embedding" << std::endl;
+    wxFrame* mf = GUI::get_main_frame();
+    std::cout << mf->GetName() << std::endl;
+    std::cout << self->GetName() << std::endl;
+    mf->SetStatusBar(self);
+}
+
+void ProgressStatusBar::SetStatusText(std::string txt)
+{
+    self->SetStatusText(txt);
+}
+
+int ProgressStatusBar::GetId()
+{
+    return self->GetId();
+}
+
+int ProgressStatusBar::GetProgId()
+{
+    return prog_->GetId();
+}
+
+}
diff --git a/xs/src/slic3r/GUI/ProgressStatusBar.hpp b/xs/src/slic3r/GUI/ProgressStatusBar.hpp
new file mode 100644
index 000000000..53366aace
--- /dev/null
+++ b/xs/src/slic3r/GUI/ProgressStatusBar.hpp
@@ -0,0 +1,61 @@
+#ifndef PROGRESSSTATUSBAR_HPP
+#define PROGRESSSTATUSBAR_HPP
+
+#include <memory>
+#include <functional>
+
+class wxTimer;
+class wxGauge;
+class wxButton;
+class wxTimerEvent;
+class wxStatusBar;
+class wxWindow;
+
+namespace Slic3r {
+
+/**
+ * @brief The ProgressStatusBar class is the widgets occupying the lower area
+ * of the Slicer main window. It consists of a message area to the left and a
+ * progress indication area to the right with an optional cancel button.
+ */
+class ProgressStatusBar {
+    wxStatusBar *self;      // we cheat! It should be the base class but: perl!
+    wxTimer *timer_;
+    wxGauge *prog_;
+    wxButton *cancelbutton_;
+public:
+
+    /// Cancel callback function type
+    using CancelFn = std::function<void()>;
+
+    ProgressStatusBar(wxWindow *parent = nullptr, int id = -1);
+    ~ProgressStatusBar();
+
+    int  get_progress() const;
+    void set_progress(int);
+    void set_range(int = 100);
+    void show_progress(bool);
+    void start_busy(int = 100);
+    void stop_busy();
+    inline bool is_busy() const { return busy_; }
+    void set_cancel_callback(CancelFn);
+    void run(int rate);
+
+    // Temporary methods to satisfy Perl side
+    void Embed();
+    void SetStatusText(std::string txt);
+    int  GetId();
+    int  GetProgId();
+
+private:
+    bool busy_ = false;
+    CancelFn cancel_cb_;
+};
+
+namespace GUI {
+    using Slic3r::ProgressStatusBar;
+}
+
+}
+
+#endif // PROGRESSSTATUSBAR_HPP
diff --git a/xs/src/slic3r/IProgressIndicator.hpp b/xs/src/slic3r/ProgressIndicator.hpp
similarity index 96%
rename from xs/src/slic3r/IProgressIndicator.hpp
rename to xs/src/slic3r/ProgressIndicator.hpp
index 704931574..49d0c251c 100644
--- a/xs/src/slic3r/IProgressIndicator.hpp
+++ b/xs/src/slic3r/ProgressIndicator.hpp
@@ -10,7 +10,7 @@ namespace Slic3r {
 /**
  * @brief Generic progress indication interface.
  */
-class IProgressIndicator {
+class ProgressIndicator {
 public:
     using CancelFn = std::function<void(void)>; // Cancel functio signature.
 
@@ -20,7 +20,7 @@ private:
 
 public:
 
-    inline virtual ~IProgressIndicator() {}
+    inline virtual ~ProgressIndicator() {}
 
     /// Get the maximum of the progress range.
     float max() const { return max_; }
diff --git a/xs/xsp/ProgressStatusBar.xsp b/xs/xsp/ProgressStatusBar.xsp
new file mode 100644
index 000000000..3b9be3ba8
--- /dev/null
+++ b/xs/xsp/ProgressStatusBar.xsp
@@ -0,0 +1,41 @@
+%module{Slic3r::XS};
+
+%{
+#include <xsinit.h>
+#include "slic3r/GUI/ProgressStatusBar.hpp"
+%}
+
+%name{Slic3r::GUI::ProgressStatusBar} class ProgressStatusBar {
+    ProgressStatusBar();
+    ~ProgressStatusBar();
+
+    int GetProgress() const
+        %code%{ RETVAL=THIS->get_progress(); %};
+
+    void SetProgress(int val)
+        %code%{ THIS->set_progress(val); %};
+
+    void SetRange(int val = 100)
+        %code%{ THIS->set_range(val); %};
+
+    void ShowProgress(bool show)
+        %code%{ THIS->show_progress(show); %};
+
+    void StartBusy(int val = 100)
+        %code%{ THIS->start_busy(val); %};
+
+    void StopBusy()
+        %code%{ THIS->stop_busy(); %};
+
+    bool IsBusy() const
+        %code%{ RETVAL=THIS->is_busy(); %};
+    
+    void Run(int rate)
+        %code%{ THIS->run(rate); %};
+
+    void Embed();
+    void SetStatusText(std::string txt);
+    int  GetId();
+    int  GetProgId();
+
+};
\ No newline at end of file
diff --git a/xs/xsp/my.map b/xs/xsp/my.map
index ba20ee236..e92db3346 100644
--- a/xs/xsp/my.map
+++ b/xs/xsp/my.map
@@ -233,8 +233,10 @@ PresetCollection*	      	O_OBJECT_SLIC3R
 Ref<PresetCollection>      	O_OBJECT_SLIC3R_T
 PresetBundle*	    		O_OBJECT_SLIC3R
 Ref<PresetBundle>    		O_OBJECT_SLIC3R_T
-TabIface*	   				O_OBJECT_SLIC3R
-Ref<TabIface> 				O_OBJECT_SLIC3R_T
+TabIface*                       O_OBJECT_SLIC3R
+Ref<TabIface> 			O_OBJECT_SLIC3R_T
+ProgressStatusBar*              O_OBJECT_SLIC3R
+Ref<ProgressStatusBar>          O_OBJECT_SLIC3R_T
 
 PresetUpdater*              O_OBJECT_SLIC3R
 Ref<PresetUpdater>          O_OBJECT_SLIC3R_T
diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt
index cee75fe26..1654bf3b0 100644
--- a/xs/xsp/typemap.xspt
+++ b/xs/xsp/typemap.xspt
@@ -213,6 +213,7 @@
 %typemap{PresetHints*};
 %typemap{Ref<PresetHints>}{simple};
 %typemap{TabIface*};
+%typemap{ProgressStatusBar*};
 
 %typemap{PrintRegionPtrs*};
 %typemap{PrintObjectPtrs*};