public function attribute($data, $context = null, $overwrite = true, $overwrite_parameter = false)
 {
     $name = $data['Name'];
     if (!$this->Id) {
         throw new InvalidArgumentException("Cowardly refusing to create an empty (universal) attribute");
     }
     /* Convention over configuration */
     $id_name = train_case(get_class($this)) . '_Id';
     if ($id_name == 'Context_Id') {
         $id_name = Context::$idField;
     }
     $parameterClause = ParameterAttribution::where($id_name, '=', $this->Id);
     $activeFields = [snake_case(get_class($this))];
     if ($context !== null) {
         $activeFields[] = 'context';
         $parameterClause = $parameterClause->where(Context::$idContext, '=', $context->Id);
     }
     $parameterAttributions = $parameterClause->whereHas('parameter', function ($q) use($name) {
         $q->where('Name', '=', $name);
     })->get()->filter(function ($pa) use($activeFields) {
         return empty(array_diff(array_values($pa->activeFields()), array_values($activeFields)));
     });
     $parameterAttribution = $parameterAttributions->first();
     $parameterAttributions->each(function ($pa) {
         $pa->delete();
     });
     if (array_key_exists('Value', $data)) {
         $value = $data['Value'];
         unset($data['Value']);
     } else {
         $value = null;
     }
     if (array_key_exists('Widget', $data)) {
         $widget = $data['Widget'];
         unset($data['Widget']);
     } else {
         $widget = null;
     }
     if (array_key_exists('Units', $data)) {
         $units = $data['Units'];
         unset($data['Units']);
     } else {
         $units = null;
     }
     if (array_key_exists('Editable', $data)) {
         $editable = $data['Editable'];
         unset($data['Editable']);
     } else {
         $editable = 2;
     }
     if ($parameterAttribution) {
         $parameter = $parameterAttribution->parameter;
         if ($overwrite) {
             $parameterAttribution->Value = $value;
             $parameterAttribution->Editable = $editable;
             $parameterAttribution->Widget = $widget;
             $parameterAttribution->Units = $units;
             $parameterAttribution->save();
         } else {
             $value = $parameterAttribution->Value;
             $editable = $parameterAttribution->Editable;
             $widget = $parameterAttribution->Widget;
             $units = $parameterAttribution->Units;
         }
     } else {
         $parameter = Parameter::whereName($data['Name'])->first();
         if (empty($parameter)) {
             $parameter = Parameter::create($data);
         } else {
             $parameter->update(array_filter($data));
         }
         /* Convention over configuration */
         $id_name = train_case(get_class($this)) . '_Id';
         if ($id_name == 'Context_Id') {
             $id_name = Context::$idField;
         }
         $type = array_key_exists('Type', $data) ? $data['Type'] : $parameter->Type;
         $widget = isset($widget) ? $widget : $parameter->Widget;
         $units = isset($units) ? $units : $parameter->Units;
         $attribution = [$id_name => $this->Id, 'Parameter_Id' => $parameter->Id, 'Value' => $value, 'Format' => $type, 'Editable' => $editable, 'Widget' => $widget, 'Units' => $units];
         if ($context !== null) {
             $attribution[Context::$idContext] = $context->Id;
         }
         $parameterAttribution = ParameterAttribution::create($attribution);
     }
     if ($parameter->Widget === null && $parameter->Units === null || $overwrite_parameter) {
         $parameter->Widget = $widget;
         $parameter->Units = $units;
     }
     $parameter->Value = $value;
     $parameter->Editable = $editable;
     $parameter->Widget = $widget;
     $parameter->Units = $units;
     $parameterAttribution->save();
     return $parameter;
 }