code: func (m *ModuleState) Equal(other *ModuleState) bool {
  	m.Lock()
  	defer m.Unlock()
  
  	// Paths must be equal
  	if !reflect.DeepEqual(m.Path, other.Path) {
  		return false
  	}
  
  	// Outputs must be equal
  	if len(m.Outputs) != len(other.Outputs) {
  		return false
  	}
  	for k, v := range m.Outputs {
  		if !other.Outputs[k].Equal(v) {
  			return false
  		}
  	}
  
  	// Dependencies must be equal. This sorts these in place but
  	// this shouldn't cause any problems.
  	sort.Strings(m.Dependencies)
  	sort.Strings(other.Dependencies)
  	if len(m.Dependencies) != len(other.Dependencies) {
  		return false
  	}
  	for i, d := range m.Dependencies {
  		if other.Dependencies[i] != d {
  			return false
  		}
  	}
  
  	// Resources must be equal
  	if len(m.Resources) != len(other.Resources) {
  		return false
  	}
  	for k, r := range m.Resources {
  		otherR, ok := other.Resources[k]
  		if !ok {
  			return false
  		}
  
  		if !r.Equal(otherR) {
  			return false
  		}
  	}
  
  	return true
  }
docs: // Equal tests whether one module state is equal to another.