added adapted from