public static Source dictionaryToCloudSource(Map<String, Object> params) throws Exception {
   Source res = new Source();
   res.setSpec(getDictionary(params, PropertyNames.SOURCE_SPEC));
   // SOURCE_METADATA and SOURCE_DOES_NOT_NEED_SPLITTING do not have to be
   // translated, because they only make sense in cloud Source objects produced by the user.
   return res;
 }
 // Represents a cloud Source as a dictionary for encoding inside the {@code SOURCE_STEP_INPUT}
 // property of CloudWorkflowStep.input.
 public static Map<String, Object> cloudSourceToDictionary(Source source) {
   // Do not translate encoding - the source's encoding is translated elsewhere
   // to the step's output info.
   Map<String, Object> res = new HashMap<>();
   addDictionary(res, PropertyNames.SOURCE_SPEC, source.getSpec());
   if (source.getMetadata() != null) {
     addDictionary(
         res,
         PropertyNames.SOURCE_METADATA,
         cloudSourceMetadataToDictionary(source.getMetadata()));
   }
   if (source.getDoesNotNeedSplitting() != null) {
     addBoolean(
         res, PropertyNames.SOURCE_DOES_NOT_NEED_SPLITTING, source.getDoesNotNeedSplitting());
   }
   return res;
 }