       @_loadManufacturersXML @_options.manufacturers
       @_loadCategoriesXML @_options.categories
       @_fetchProductTypes()
+      @_fetchCategories()
       ],
-      (mappingData, productsData, manufacturersData, categoriesData, productTypesData) =>
-        @logger.debug "mappingData:\n#{mappingData}"
-        @logger.debug "productsData:\n#{utils.pretty productsData}"
-        @logger.debug "productTypesData:\n#{utils.pretty productTypesData}"
-        @mapping = JSON.parse mappingData
-        @toBeImported = _.size(productsData.Products?.Product)
-        productType = @_getProductType productTypesData
-        manufacturers = @_processManufacturers(manufacturersData, productType) if manufacturersData
-        @_updateProductType(productType, manufacturers) if manufacturers
-        @_updateCategories categoriesData if categoriesData
-        products = @_buildProductsData(productsData, productType)
-        @logger.info "[Products] About to create '#{_.size products}' products."
-        @_batch _.map(products, (p) => @_createProduct p), 100
+      (mapping, productsXML, manufacturersXML, categoriesXML, fetchedProductTypes, fetchedCategories) =>
+        @logger.debug "mapping:\n#{mapping}"
+        @logger.debug "productsXML:\n#{utils.pretty productsXML}"
+        @logger.debug "fetchedProductTypes:\n#{utils.pretty fetchedProductTypes}"
+        @mapping = JSON.parse mapping
+        @productsXML = productsXML
+        @categoriesXML = categoriesXML
+        @fetchedCategories = @_transformByCategoryExternalId fetchedCategories.results
+        @toBeImported = _.size(productsXML.Products?.Product)
+        @productType = @_getProductType fetchedProductTypes
+        manufacturers = @_buildManufacturers(manufacturersXML, @productType) if manufacturersXML
+        @_updateProductType(@productType, manufacturers) if manufacturers
+    .then (productTypeUpdateResult) =>
+      @categories = @_buildCategories(@categoriesXML) if @categoriesXML
+      creates = @_buildCategoryCreates(@categories, @fetchedCategories) if @categories
+      @_batch(_.map(creates, (c) => @_createCategory c), 100) if creates
+    .then (createCategoriesResult) =>
+      # fetch created categories to get id's used for parent reference creation
+      @_fetchCategories()
+    .then (fetchedCategories) =>
+      @fetchedCategories = @_transformByCategoryExternalId fetchedCategories.result
+      updates = @_buildCategoryUpdates(@categories, @fetchedCategories) if @categories
+      @_batch(_.map(updates, (c) => @_updateCategory c), 100) if updates
+    .then (updateCategoriesResult) =>
+      @logger.info '[Products] Products import started...'
+      products = @_buildProducts(@productsXML, @productType, @fetchedCategories)
+      @logger.info "[Products] About to create '#{_.size products}' products."
+      @_batch(_.map(products, (p) => @_createProduct p), 100) if products
     .fail (error) =>
       @logger.error "Error on execute method; #{error}"
       @logger.error "Error stack: #{error.stack}" if error.stack
       @_processResult(callback)
     .done (result) =>
       @_processResult(callback)
-
 
   _processResult: (callback) ->
     endTime = new Date().getTime()

  _loadCategoriesXML: (path) ->
    utils.xmlToJson(path) if path

  _processManufacturers: (manufacturersData, productType) ->
    @logger.info '[Manufacturers] Update manufacturers started...'
    @logger.debug "[Manufacturers] manufacturersData:\n#{utils.pretty manufacturersData}"

    if not @mapping.productMapping.ManufacturerId
      @logger.info '[Manufacturers] Mmapping for ManufacturerId is not defined. No manufacturers will be created.'
      return

    count = manufacturersData.Manufacturers?['$'].count
    if count
      @logger.info "[Manufacturers] Manufacturers found: '#{count}'"
    else

      @_processImages(item, product, variant)

    variant

  _processCategories: (product, data) ->
    catReferences = []
    _.each data.Categories?.Category, (c) =>
      categoryId = c.CategoryId[0]
      existingCategory = @_getCategoryByExternalId(categoryId, fetchedCategories)
      id = existingCategory.id
      reference =
        typeId: "category"
        id: id
      catReferences.push reference

    if _.size(catReferences) > 0
      product.categories = catReferences

  _processImages: (item, product, variant) ->
    _.each item, (value, key) =>
