def new_subnet_address_prefix(vnet_address_prefix, subnets)
      if subnets.empty? ## no subnets exist in the given address space of the virtual network, so divide the network into smaller subnets (based on the network size) and allocate space for the new subnet to be added ##
        divide_network(vnet_address_prefix)
      else ## subnets exist in vnet, calculate new address_prefix for the new subnet based on the space taken by these existing subnets under the given address space of the virtual network ##
        vnet_network_address = IPAddress(vnet_address_prefix)
        subnets = sort_subnets_by_cidr_prefix(subnets)
        available_networks_pool = Array.new
        used_networks_pool = Array.new
        subnets.each do |subnet|
          ## in case the larger network is not divided into smaller subnets but
          ## divided into only 1 largest subnet of the complete network size ##
          if vnet_network_address.prefix == subnet_cidr_prefix(subnet)
            break
          end

          ## add all the possible subnets (calculated using the current subnet's
          ## cidr prefix value) into the available_networks_pool ##
          available_networks_pool.push(
            vnet_network_address.subnet(subnet_cidr_prefix(subnet))
          ).flatten!.uniq! { |nwrk| [ nwrk.network.address, nwrk.prefix ].join(":") }

          ## add current subnet into the used_networks_pool ##
          used_networks_pool.push(
            IPAddress(subnet_address_prefix(subnet))
          )

          ## sort both the network pools before trimming the available_networks_pool ##
          available_networks_pool, used_networks_pool = sort_pools(
            available_networks_pool, used_networks_pool)

          ## trim the available_networks_pool based on the networks already
          ## allocated to the existing subnets ##
          used_networks_pool.each do |subnet_network|
            available_networks_pool.delete_if do |available_network|
              in_use_network?(subnet_network, available_network)
            end
          end

          ## sort both the network pools after trimming the available_networks_pool ##
          available_networks_pool, used_networks_pool = sort_pools(
            available_networks_pool, used_networks_pool)
        end

        ## space available in the vnet_address_prefix network for the new subnet ##
        if !available_networks_pool.empty? && available_networks_pool.first.network?
          available_networks_pool.first.network.address.concat("/" + available_networks_pool.first.prefix.to_s)
        else ## space not available in the vnet_address_prefix network for the new subnet ##
          nil
        end
      end
    end
def new_subnet_address_prefix(vnet_address_prefix, subnets)
      if subnets.empty? ## no subnets exist in the given address space of the virtual network, so divide the network into smaller subnets (based on the network size) and allocate space for the new subnet to be added ##
        divide_network(vnet_address_prefix)
      else ## subnets exist in vnet, calculate new address_prefix for the new subnet based on the space taken by these existing subnets under the given address space of the virtual network ##
        vnet_network_address = IPAddress(vnet_address_prefix)
        subnets = sort_subnets_by_cidr_prefix(subnets)
        available_networks_pool = Array.new
        used_networks_pool = Array.new
        subnets.each do |subnet|
          ## in case the larger network is not divided into smaller subnets but
          ## divided into only 1 largest subnet of the complete network size ##
          if vnet_network_address.prefix == subnet_cidr_prefix(subnet)
            break
          end

          ## add all the possible subnets (calculated using the current subnet's
          ## cidr prefix value) into the available_networks_pool ##
          available_networks_pool.push(
            vnet_network_address.subnet(subnet_cidr_prefix(subnet))
          ).flatten!.uniq! { |nwrk| [ nwrk.network.address, nwrk.prefix ].join(":") }

          ## add current subnet into the used_networks_pool ##
          used_networks_pool.push(
            IPAddress(subnet_address_prefix(subnet))
          )

          ## sort both the network pools before trimming the available_networks_pool ##
          available_networks_pool, used_networks_pool = sort_pools(
            available_networks_pool, used_networks_pool)

          ## trim the available_networks_pool based on the networks already
          ## allocated to the existing subnets ##
          used_networks_pool.each do |subnet_network|
            available_networks_pool.delete_if do |available_network|
              in_use_network?(subnet_network, available_network)
            end
          end

          ## sort both the network pools after trimming the available_networks_pool ##
          available_networks_pool, used_networks_pool = sort_pools(
            available_networks_pool, used_networks_pool)
        end

        ## space available in the vnet_address_prefix network for the new subnet ##
        if !available_networks_pool.empty? && available_networks_pool.first.network?
          available_networks_pool.first.network.address.concat("/" + available_networks_pool.first.prefix.to_s)
        else ## space not available in the vnet_address_prefix network for the new subnet ##
          nil
        end
      end
    end
calculate and return address_prefix for the new subnet to be added in the
 existing virtual network