public static function init($instance_name, $save_on_demand){

        $request = app('request');
        $session_id = $request->session()->getId();
        $user_id = config('cart.user_id');
        $app = Application::getInstance();
        $carts = $app->offsetGet("cart_instances");

        if ($user_id instanceof \Closure)
            $user_id = $user_id();

        //if user logged in
        if( $user_id ){
            $user_cart = static::active()->user()->where('name', $instance_name)->first();

            $session_cart_id = $request->session()->get('cart_'.$instance_name);
            $session_cart = is_null($session_cart_id)? null: static::active()->session($session_cart_id)->where('name', $instance_name)->first();

            switch (true) {

                case is_null($user_cart) && is_null($session_cart): //no user cart or session cart
                    $attributes = array(
                        'user_id' => $user_id,
                        'name' => $instance_name,
                        'status' => STATUS_ACTIVE
                    );
                    if($save_on_demand)
                        $cart = new static($attributes);
                    else
                        $cart = static::create($attributes);

                    break;

                case !is_null($user_cart) && is_null($session_cart): //only user cart
                    $cart = $user_cart;
                    break;

                case is_null($user_cart) && !is_null($session_cart): //only session cart
                    $cart = $session_cart;
                    $cart->user_id = $user_id;
                    $cart->session = null;
                    $cart->save();
                    break;

                case !is_null($user_cart) && !is_null($session_cart): //both user cart and session cart exists
                    $session_cart->moveItemsTo($user_cart); //move items from session cart to user cart
                    $session_cart->delete(); //delete session cart
                    $cart = $user_cart;
                    break;
            }

            $request->session()->forget('cart_'.$instance_name); //no longer need it.
            $carts[$instance_name] = $cart;
        }
        //guest user, create cart with session id
        else{
            $attributes = array(
                'session' => $session_id,
                'name' => $instance_name,
                'status' => STATUS_ACTIVE
            );
            $cart = static::firstOrNew($attributes);

            if(!$save_on_demand)
                $cart->save();

            //save current session id, since upon login session id will be regenerated
            //we will use this id to get back the cart before login
            $request->session()->put('cart_'.$instance_name, $session_id);
            $carts[$instance_name] = $cart;
        }
        $app->offsetSet("cart_instances", $carts);
        return $carts[$instance_name];
    }