diff --git a/osm_lcm/data_utils/database/wim_account.py b/osm_lcm/data_utils/database/wim_account.py
new file mode 100644
index 0000000..8b0b5f6
--- /dev/null
+++ b/osm_lcm/data_utils/database/wim_account.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# This file is part of OSM Life-Cycle Management module
+#
+# Copyright 2022 ETSI
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+##
+
+from osm_lcm.data_utils.database.database import Database
+
+__author__ = (
+    "Lluis Gifre <lluis.gifre@cttc.es>, Ricard Vilalta <ricard.vilalta@cttc.es>"
+)
+
+
+class WimAccountDB:
+    db = None
+    db_wims = {}
+
+    def initialize_db():
+        WimAccountDB.db = Database().instance.db
+
+    def get_wim_account_with_id(wim_account_id):
+        if not WimAccountDB.db:
+            WimAccountDB.initialize_db()
+        if wim_account_id in WimAccountDB.db_wims:
+            return WimAccountDB.db_wims[wim_account_id]
+        db_wim = WimAccountDB.db.get_one("wim_accounts", {"_id": wim_account_id}) or {}
+        WimAccountDB.db_wims[wim_account_id] = db_wim
+        return db_wim
+
+    def get_all_wim_accounts():
+        if not WimAccountDB.db:
+            WimAccountDB.initialize_db()
+        db_wims_list = WimAccountDB.db.get_list("wim_accounts")
+        WimAccountDB.db_wims.update({db_wim["_id"]: db_wim for db_wim in db_wims_list})
+        return WimAccountDB.db_wims
diff --git a/osm_lcm/data_utils/vim.py b/osm_lcm/data_utils/vim.py
index 0e69572..2042fd82 100644
--- a/osm_lcm/data_utils/vim.py
+++ b/osm_lcm/data_utils/vim.py
@@ -21,3 +21,59 @@
 # For those usages not covered by the Apache License, Version 2.0 please
 # contact: fbravo@whitestack.com
 ##
+
+from osm_lcm.data_utils.database.vim_account import VimAccountDB
+
+__author__ = (
+    "Lluis Gifre <lluis.gifre@cttc.es>, Ricard Vilalta <ricard.vilalta@cttc.es>"
+)
+
+
+def get_vims_to_connect(db_nsr, db_vnfrs, target_vld, logger):
+    vims_to_connect = set()
+    vld = next(
+        (vld for vld in db_nsr["vld"] if vld["id"] == target_vld["id"]),
+        None,
+    )
+    if vld is None:
+        return vims_to_connect  # VLD not in NS, means it is an internal VLD within a single VIM
+
+    vim_ids = set()
+    if "vnfd-connection-point-ref" in vld:
+        # during planning of VNF, use "vnfd-connection-point-ref" since "vim_info" is not available in vld
+        # get VNFD connection points (if available)
+        # iterate over VNFs and retrieve VIM IDs they are planned to be deployed to
+        vnfd_connection_point_ref = vld["vnfd-connection-point-ref"]
+        for vld_member_vnf_index_ref in vnfd_connection_point_ref:
+            vld_member_vnf_index_ref = vld_member_vnf_index_ref["member-vnf-index-ref"]
+            vim_ids.add(db_vnfrs[vld_member_vnf_index_ref]["vim-account-id"])
+    elif "vim_info" in vld:
+        # after instantiation of VNF, use "vim_info" since "vnfd-connection-point-ref" is not available in vld
+        # get VIM info (if available)
+        # iterate over VIM info and retrieve VIM IDs they are deployed to
+        vim_info = vld["vim_info"]
+        for vim_data in vim_info.values():
+            vim_ids.add(vim_data["vim_account_id"])
+    else:
+        # TODO: analyze if this situation is possible
+        # unable to retrieve planned/executed mapping of VNFs to VIMs
+        # by now, drop a log message for future debugging
+        logger.warning(
+            " ".join(
+                [
+                    "Unable to identify VIMs involved in VLD to check if WIM is required.",
+                    "Dumping internal variables for further debugging:",
+                ]
+            )
+        )
+        logger.warning("db_nsr={:s}".format(str(db_nsr)))
+        logger.warning("db_vnfrs={:s}".format(str(db_vnfrs)))
+        logger.warning("target_vld={:s}".format(str(target_vld)))
+        return vims_to_connect
+
+    for vim_id in vim_ids:
+        db_vim = VimAccountDB.get_vim_account_with_id(vim_id)
+        if db_vim is None:
+            continue
+        vims_to_connect.add(db_vim["name"])
+    return vims_to_connect
diff --git a/osm_lcm/data_utils/wim.py b/osm_lcm/data_utils/wim.py
new file mode 100644
index 0000000..c8ce0bf
--- /dev/null
+++ b/osm_lcm/data_utils/wim.py
@@ -0,0 +1,166 @@
+# -*- coding: utf-8 -*-
+
+# This file is part of OSM Life-Cycle Management module
+#
+# Copyright 2022 ETSI
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+##
+
+
+from osm_lcm.data_utils.database.vim_account import VimAccountDB
+from osm_lcm.data_utils.database.wim_account import WimAccountDB
+from osm_lcm.data_utils.vim import get_vims_to_connect
+from osm_lcm.lcm_utils import LcmException
+
+__author__ = (
+    "Lluis Gifre <lluis.gifre@cttc.es>, Ricard Vilalta <ricard.vilalta@cttc.es>"
+)
+
+
+def get_candidate_wims(vims_to_connect):
+    all_wim_accounts = WimAccountDB.get_all_wim_accounts()
+    candidate_wims = {}
+    for wim_id, db_wim in all_wim_accounts.items():
+        wim_port_mapping = db_wim.get("config", {}).get("wim_port_mapping", [])
+        wim_dc_ids = {
+            m.get("datacenter_id") for m in wim_port_mapping if m.get("datacenter_id")
+        }
+        not_reachable_vims = vims_to_connect.difference(wim_dc_ids)
+        if len(not_reachable_vims) > 0:
+            continue
+        # TODO: consider adding other filtering fields such as supported layer(s) [L2, L3, ...]
+        candidate_wims[wim_id] = db_wim
+    return candidate_wims
+
+
+def select_feasible_wim_account(db_nsr, db_vnfrs, target_vld, vld_params, logger):
+    logger.info("Checking if WIM is needed for VLD({:s})...".format(str(target_vld)))
+    if target_vld.get("mgmt-network", False):
+        logger.info(
+            "WIM not needed, VLD({:s}) is a management network".format(str(target_vld))
+        )
+        return None, None  # assume mgmt networks do not use a WIM
+
+    # check if WIM account is explicitly False
+    wim_account_id = vld_params.get("wimAccountId")
+    if wim_account_id is not None and not wim_account_id:
+        logger.info(
+            "VLD({:s}) explicitly specifies not to use a WIM".format(str(target_vld))
+        )
+        return None, None  # WIM account explicitly set to False, do not use a WIM
+
+    # find VIMs to be connected by VLD
+    vims_to_connect = get_vims_to_connect(db_nsr, db_vnfrs, target_vld, logger)
+    # check if we need a WIM to interconnect the VNFs in different VIMs
+    if len(vims_to_connect) < 2:
+        logger.info(
+            "WIM not needed, VLD({:s}) does not involve multiple VIMs".format(
+                str(target_vld)
+            )
+        )
+        return None, None
+    # if more than one VIM needs to be connected...
+    logger.info(
+        "WIM is needed, multiple VIMs to interconnect: {:s}".format(
+            str(vims_to_connect)
+        )
+    )
+    # find a WIM having these VIMs on its wim_port_mapping setting
+    candidate_wims = get_candidate_wims(vims_to_connect)
+    logger.info("Candidate WIMs: {:s}".format(str(candidate_wims)))
+
+    # check if a desired wim_account_id is specified in vld_params
+    wim_account_id = vld_params.get("wimAccountId")
+    if wim_account_id:
+        # check if the desired WIM account is feasible
+        # implicitly checks if it exists in the DB
+        db_wim = candidate_wims.get(wim_account_id)
+        if db_wim:
+            return wim_account_id, db_wim
+        msg = (
+            "WimAccountId specified in VldParams({:s}) cannot be used "
+            "to connect the required VIMs({:s}). Candidate WIMs are: {:s}"
+        )
+        raise LcmException(
+            msg.format(str(vld_params), str(vims_to_connect), str(candidate_wims))
+        )
+
+    # if multiple candidate WIMs: report error message
+    if len(candidate_wims) > 1:
+        msg = (
+            "Multiple candidate WIMs found ({:s}) and wim_account not specified. "
+            "Please, specify the WIM account to be used."
+        )
+        raise LcmException(msg.format(str(candidate_wims.keys())))
+
+    # a single candidate WIM has been found, retrieve it
+    return candidate_wims.popitem()  # returns tuple (wim_account_id, db_wim)
+
+
+def get_target_wim_attrs(nsr_id, target_vld, vld_params):
+    target_vims = [
+        "vim:{:s}".format(vim_id) for vim_id in vld_params["vim-network-name"]
+    ]
+    wim_vld = "nsrs:{}:vld.{}".format(nsr_id, target_vld["id"])
+    vld_type = target_vld.get("type")
+    if vld_type is None:
+        vld_type = "ELAN" if len(target_vims) > 2 else "ELINE"
+    target_wim_attrs = {
+        "sdn": True,
+        "target_vims": target_vims,
+        "vlds": [wim_vld],
+        "type": vld_type,
+    }
+    return target_wim_attrs
+
+
+def get_sdn_ports(vld_params, db_wim):
+    if vld_params.get("provider-network"):
+        # if SDN ports are specified in VLD params, use them
+        return vld_params["provider-network"].get("sdn-ports")
+
+    # otherwise, compose SDN ports required
+    wim_port_mapping = db_wim.get("config", {}).get("wim_port_mapping", [])
+    sdn_ports = []
+    for vim_id in vld_params["vim-network-name"]:
+        db_vim = VimAccountDB.get_vim_account_with_id(vim_id)
+        vim_name = db_vim["name"]
+        mapping = next(
+            (m for m in wim_port_mapping if m["datacenter_id"] == vim_name),
+            None,
+        )
+        if mapping is None:
+            msg = "WIM({:s},{:s}) does not specify a mapping for VIM({:s},{:s})"
+            raise LcmException(
+                msg.format(
+                    db_wim["name"],
+                    db_wim["_id"],
+                    db_vim["name"],
+                    db_vim["_id"],
+                )
+            )
+        sdn_port = {
+            "device_id": vim_name,
+            "switch_id": mapping.get("device_id"),
+            "switch_port": mapping.get("device_interface_id"),
+            "service_endpoint_id": mapping.get("service_endpoint_id"),
+        }
+        service_mapping_info = mapping.get("service_mapping_info", {})
+        encapsulation = service_mapping_info.get("encapsulation", {})
+        if encapsulation.get("type"):
+            sdn_port["service_endpoint_encapsulation_type"] = encapsulation["type"]
+        if encapsulation.get("vlan"):
+            sdn_port["vlan"] = encapsulation["vlan"]
+        sdn_ports.append(sdn_port)
+    return sdn_ports
