docs: @Override
      public void processMessage() {
          // this only picks up new training round
          //log.info("sI_{} Starting CBOW dot...", transport.getShardIndex());
  
          CbowRequestMessage cbrm = new CbowRequestMessage(rowsA, rowsB, w1, codes, negSamples, alpha, 119);
          if (negSamples > 0) {
              // unfortunately we have to get copy of negSamples here
              int negatives[] = Arrays.copyOfRange(rowsB, codes.length, rowsB.length);
              cbrm.setNegatives(negatives);
          }
          cbrm.setFrameId(-119L);
          cbrm.setTaskId(this.taskId);
          cbrm.setOriginatorId(this.getOriginatorId());
  
  
          // FIXME: get rid of THAT
          CbowTrainer cbt = (CbowTrainer) trainer;
          cbt.pickTraining(cbrm);
  
  
          // we calculate dot for all involved rows, and first of all we get mean word
          INDArray words = Nd4j.pullRows(storage.getArray(WordVectorStorage.SYN_0), 1, rowsA, 'c');
          INDArray mean = words.mean(0);
  
          int resultLength = codes.length + (negSamples > 0 ? (negSamples + 1) : 0);
  
          INDArray result = Nd4j.createUninitialized(resultLength, 1);
          int e = 0;
          for (; e < codes.length; e++) {
              double dot = Nd4j.getBlasWrapper().dot(mean, storage.getArray(WordVectorStorage.SYN_1).getRow(rowsB[e]));
              result.putScalar(e, dot);
          }
  
          // negSampling round
          for (; e < resultLength; e++) {
              double dot = Nd4j.getBlasWrapper().dot(mean,
                              storage.getArray(WordVectorStorage.SYN_1_NEGATIVE).getRow(rowsB[e]));
              result.putScalar(e, dot);
          }
  
          if (voidConfiguration.getExecutionMode() == ExecutionMode.AVERAGING) {
              DotAggregation dot = new DotAggregation(taskId, (short) 1, shardIndex, result);
              dot.setTargetId((short) -1);
              dot.setOriginatorId(getOriginatorId());
              transport.putMessage(dot);
          } else if (voidConfiguration.getExecutionMode() == ExecutionMode.SHARDED) {
              // send this message to everyone
              DotAggregation dot = new DotAggregation(taskId, (short) voidConfiguration.getNumberOfShards(), shardIndex,
                              result);
              dot.setTargetId((short) -1);
              dot.setOriginatorId(getOriginatorId());
              transport.sendMessage(dot);
          }
      }