added multi-threading