Best Selenium code snippet using org.openqa.selenium.ImmutableCapabilities.hashCode
Source:NodeStatus.java
...84 Objects.equals(this.stereotypes, that.stereotypes) &&85 Objects.equals(this.snapshot, that.snapshot);86 }87 @Override88 public int hashCode() {89 return Objects.hash(nodeId, externalUri, maxSessionCount, stereotypes, snapshot);90 }91 private Map<String, Object> toJson() {92 return ImmutableMap.of(93 "id", nodeId,94 "uri", externalUri,95 "maxSessions", maxSessionCount,96 "stereotypes", asCapacity(stereotypes),97 "sessions", snapshot);98 }99 private List<Map<String, Object>> asCapacity(Map<Capabilities, Integer> toConvert) {100 ImmutableList.Builder<Map<String, Object>> toReturn = ImmutableList.builder();101 toConvert.forEach((caps, count) -> {102 toReturn.add(ImmutableMap.of(103 "capabilities", caps,104 "count", count));105 });106 return toReturn.build();107 }108 public static NodeStatus fromJson(Map<String, Object> raw) {109 List<Active> sessions = ((Collection<?>) raw.get("sessions")).stream()110 .map(item -> {111 @SuppressWarnings("unchecked")112 Map<String, Object> converted = (Map<String, Object>) item;113 return converted;114 })115 .map(Active::fromJson)116 .collect(toImmutableList());117 try {118 return new NodeStatus(119 UUID.fromString((String) raw.get("id")),120 new URI((String) raw.get("uri")),121 ((Number) raw.get("maxSessions")).intValue(),122 readCapacityNamed(raw, "stereotypes"),123 sessions);124 } catch (URISyntaxException e) {125 throw new JsonException(e);126 }127 }128 private static Map<Capabilities, Integer> readCapacityNamed(129 Map<String, Object> raw,130 String name) {131 ImmutableMap.Builder<Capabilities, Integer> capacity = ImmutableMap.builder();132 ((Collection<?>) raw.get(name)).forEach(obj -> {133 Map<?, ?> cap = (Map<?, ?>) obj;134 capacity.put(135 new ImmutableCapabilities((Map<?, ?>) cap.get("capabilities")),136 ((Number) cap.get("count")).intValue());137 });138 return capacity.build();139 }140 public static class Active {141 private final Capabilities stereotype;142 private final SessionId id;143 private final Capabilities currentCapabilities;144 public Active(Capabilities stereotype, SessionId id, Capabilities currentCapabilities) {145 this.stereotype = ImmutableCapabilities.copyOf(Objects.requireNonNull(stereotype));146 this.id = Objects.requireNonNull(id);147 this.currentCapabilities =148 ImmutableCapabilities.copyOf(Objects.requireNonNull(currentCapabilities));149 }150 public Capabilities getStereotype() {151 return stereotype;152 }153 public SessionId getSessionId() {154 return id;155 }156 public Capabilities getCurrentCapabilities() {157 return currentCapabilities;158 }159 @Override160 public boolean equals(Object o) {161 if (!(o instanceof Active)) {162 return false;163 }164 Active that = (Active) o;165 return Objects.equals(this.getStereotype(), that.getStereotype()) &&166 Objects.equals(this.id, that.id) &&167 Objects.equals(this.getCurrentCapabilities(), that.getCurrentCapabilities());168 }169 @Override170 public int hashCode() {171 return Objects.hash(getStereotype(), id, getCurrentCapabilities());172 }173 private Map<String, Object> toJson() {174 return ImmutableMap.of(175 "sessionId", getSessionId(),176 "stereotype", getStereotype(),177 "currentCapabilities", getCurrentCapabilities());178 }179 private static Active fromJson(Map<String, Object> raw) {180 SessionId id = new SessionId((String) raw.get("sessionId"));181 Capabilities stereotype = new ImmutableCapabilities((Map<?, ?>) raw.get("stereotype"));182 Capabilities current = new ImmutableCapabilities((Map<?, ?>) raw.get("currentCapabilities"));183 return new Active(stereotype, id, current);184 }...
Source:ImmutableCapabilities.java
...23import java.util.TreeMap;24import static org.openqa.selenium.SharedCapabilitiesMethods.setCapability;25public class ImmutableCapabilities implements Capabilities {26 private final Map<String, Object> delegate;27 private final int hashCode;28 public ImmutableCapabilities() {29 this.delegate = Collections.emptyMap();30 this.hashCode = SharedCapabilitiesMethods.hashCode(this);31 }32 public ImmutableCapabilities(String k, Object v) {33 Require.nonNull("Capability", k);34 Require.nonNull("Value", v);35 Map<String, Object> delegate = new TreeMap<>();36 setCapability(delegate, k, v);37 this.delegate = Collections.unmodifiableMap(delegate);38 this.hashCode = SharedCapabilitiesMethods.hashCode(this);39 }40 public ImmutableCapabilities(String k1, Object v1, String k2, Object v2) {41 Require.nonNull("First capability", k1);42 Require.nonNull("First value", v1);43 Require.nonNull("Second capability", k2);44 Require.nonNull("Second value", v2);45 Map<String, Object> delegate = new TreeMap<>();46 setCapability(delegate, k1, v1);47 setCapability(delegate, k2, v2);48 this.delegate = Collections.unmodifiableMap(delegate);49 this.hashCode = SharedCapabilitiesMethods.hashCode(this);50 }51 public ImmutableCapabilities(String k1, Object v1, String k2, Object v2, String k3, Object v3) {52 Require.nonNull("First capability", k1);53 Require.nonNull("First value", v1);54 Require.nonNull("Second capability", k2);55 Require.nonNull("Second value", v2);56 Require.nonNull("Third capability", k3);57 Require.nonNull("Third value", v3);58 Map<String, Object> delegate = new TreeMap<>();59 setCapability(delegate, k1, v1);60 setCapability(delegate, k2, v2);61 setCapability(delegate, k3, v3);62 this.delegate = Collections.unmodifiableMap(delegate);63 this.hashCode = SharedCapabilitiesMethods.hashCode(this);64 }65 public ImmutableCapabilities(66 String k1, Object v1,67 String k2, Object v2,68 String k3, Object v3,69 String k4, Object v4) {70 Require.nonNull("First capability", k1);71 Require.nonNull("First value", v1);72 Require.nonNull("Second capability", k2);73 Require.nonNull("Second value", v2);74 Require.nonNull("Third capability", k3);75 Require.nonNull("Third value", v3);76 Require.nonNull("Fourth capability", k4);77 Require.nonNull("Fourth value", v4);78 Map<String, Object> delegate = new TreeMap<>();79 setCapability(delegate, k1, v1);80 setCapability(delegate, k2, v2);81 setCapability(delegate, k3, v3);82 setCapability(delegate, k4, v4);83 this.delegate = Collections.unmodifiableMap(delegate);84 this.hashCode = SharedCapabilitiesMethods.hashCode(this);85 }86 public ImmutableCapabilities(87 String k1, Object v1,88 String k2, Object v2,89 String k3, Object v3,90 String k4, Object v4,91 String k5, Object v5) {92 Require.nonNull("First capability", k1);93 Require.nonNull("First value", v1);94 Require.nonNull("Second capability", k2);95 Require.nonNull("Second value", v2);96 Require.nonNull("Third capability", k3);97 Require.nonNull("Third value", v3);98 Require.nonNull("Fourth capability", k4);99 Require.nonNull("Fourth value", v4);100 Require.nonNull("Fifth capability", k5);101 Require.nonNull("Fifth value", v5);102 Map<String, Object> delegate = new TreeMap<>();103 setCapability(delegate, k1, v1);104 setCapability(delegate, k2, v2);105 setCapability(delegate, k3, v3);106 setCapability(delegate, k4, v4);107 setCapability(delegate, k5, v5);108 this.delegate = Collections.unmodifiableMap(delegate);109 this.hashCode = SharedCapabilitiesMethods.hashCode(this);110 }111 public ImmutableCapabilities(Capabilities other) {112 Require.nonNull("Capabilities", other);113 Map<String, Object> delegate = new TreeMap<>();114 other.getCapabilityNames().forEach(name -> {115 Require.nonNull("Capability name", name);116 Object value = other.getCapability(name);117 Require.nonNull("Capability value", value);118 setCapability(delegate, name, value);119 });120 this.delegate = Collections.unmodifiableMap(delegate);121 this.hashCode = SharedCapabilitiesMethods.hashCode(this);122 }123 public ImmutableCapabilities(Map<?, ?> capabilities) {124 Require.nonNull("Capabilities", capabilities);125 Map<String, Object> delegate = new TreeMap<>();126 capabilities.forEach((key, value) -> {127 Require.argument("Capability key", key).instanceOf(String.class);128 Object v = capabilities.get(key);129 Require.nonNull("Capability value", value);130 setCapability(delegate, (String) key, v);131 });132 this.delegate = Collections.unmodifiableMap(delegate);133 this.hashCode = SharedCapabilitiesMethods.hashCode(this);134 }135 @Override136 public Object getCapability(String capabilityName) {137 Require.nonNull("Capability name", capabilityName);138 return delegate.get(capabilityName);139 }140 @Override141 public Map<String, Object> asMap() {142 return delegate;143 }144 @Override145 public int hashCode() {146 return hashCode;147 }148 @Override149 public boolean equals(Object o) {150 if (!(o instanceof Capabilities)) {151 return false;152 }153 return SharedCapabilitiesMethods.equals(this, (Capabilities) o);154 }155 @Override156 public String toString() {157 return SharedCapabilitiesMethods.toString(this);158 }159 public static ImmutableCapabilities copyOf(Capabilities capabilities) {160 Require.nonNull("Capabilities", capabilities);...
Source:CapabilitiesTest.java
...107 Capabilities one = new ImmutableCapabilities("key1", "value1", "key2", "value2");108 Capabilities two = new MutableCapabilities(ImmutableMap.of("key1", "value1", "key2", "value2"));109 Capabilities three = new PersistentCapabilities(new ImmutableCapabilities("key2", "value2"))110 .setCapability("key1", "value1");111 assertThat(one.hashCode()).isEqualTo(two.hashCode());112 assertThat(one.hashCode()).isEqualTo(three.hashCode());113 assertThat(two.hashCode()).isEqualTo(three.hashCode());114 }115}...
Source:Session.java
...109 return Objects.equals(id, session.getId()) &&110 Objects.equals(uri, session.getUri());111 }112 @Override113 public int hashCode() {114 return Objects.hash(id, uri);115 }116}...
Source:PersistentCapabilities.java
...25import java.util.stream.Stream;26public class PersistentCapabilities implements Capabilities {27 private final ImmutableCapabilities caps;28 private final ImmutableCapabilities overrides;29 private final int hashCode;30 public PersistentCapabilities() {31 this(new ImmutableCapabilities());32 }33 public PersistentCapabilities(Capabilities source) {34 this(source, new ImmutableCapabilities());35 }36 private PersistentCapabilities(Capabilities previousValues, Capabilities newValues) {37 Require.nonNull("Source capabilities", previousValues, "may be empty, but must be set.");38 Require.nonNull("Additional capabilities", newValues, "may be empty, but must be set.");39 this.caps = ImmutableCapabilities.copyOf(previousValues);40 this.overrides = ImmutableCapabilities.copyOf(newValues);41 this.hashCode = SharedCapabilitiesMethods.hashCode(this);42 }43 public PersistentCapabilities setCapability(String name, Object value) {44 Require.nonNull("Name", name);45 Require.nonNull("Value", value);46 return new PersistentCapabilities(this, new ImmutableCapabilities(name, value));47 }48 @Override49 public Map<String, Object> asMap() {50 return getCapabilityNames().stream()51 .collect(toUnmodifiableMap(Function.identity(), this::getCapability));52 }53 @Override54 public Object getCapability(String capabilityName) {55 Require.nonNull("Capability name", capabilityName);56 Object capability = overrides.getCapability(capabilityName);57 if (capability != null) {58 return capability;59 }60 return caps.getCapability(capabilityName);61 }62 @Override63 public Capabilities merge(Capabilities other) {64 Require.nonNull("Other capabilities", other, "may be empty, but must be set.");65 return new PersistentCapabilities(this, other);66 }67 @Override68 public Set<String> getCapabilityNames() {69 return Stream.concat(caps.getCapabilityNames().stream(), overrides.getCapabilityNames().stream())70 .collect(toUnmodifiableSet());71 }72 // Needed, since we're dependent on Java 8 as a minimum version73 private <T, K, U> Collector<T, ?, Map<K, U>> toUnmodifiableMap(74 Function<? super T, ? extends K> keyMapper,75 Function<? super T, ? extends U> valueMapper) {76 return Collectors.collectingAndThen(Collectors.toMap(keyMapper, valueMapper), Collections::unmodifiableMap);77 }78 // Needed, since we're dependent on Java 8 as a minimum version79 private <T> Collector<T, ?, Set<T>> toUnmodifiableSet() {80 return Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet);81 }82 @Override83 public String toString() {84 return SharedCapabilitiesMethods.toString(this);85 }86 @Override87 public int hashCode() {88 return hashCode;89 }90 @Override91 public boolean equals(Object o) {92 if (!(o instanceof Capabilities)) {93 return false;94 }95 return SharedCapabilitiesMethods.equals(this, (Capabilities) o);96 }97}...
hashCode
Using AI Code Generation
1package com.automation;2import java.util.ArrayList;3import java.util.Arrays;4import java.util.List;5import org.openqa.selenium.Capabilities;6import org.openqa.selenium.ImmutableCapabilities;7import org.openqa.selenium.Platform;8import org.openqa.selenium.remote.DesiredCapabilities;9public class HashCodeExample {10 public static void main(String[] args) {11 List<Capabilities> caps = new ArrayList<Capabilities>();12 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.ANY));13 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.ANY));14 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.ANY));15 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.ANY));16 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.WINDOWS));17 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.WINDOWS));18 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.MAC));19 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.MAC));20 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.WINDOWS));21 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.WINDOWS));22 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.MAC));23 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.MAC));24 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.LINUX));25 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.LINUX));26 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.LINUX));27 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.LINUX));28 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.ANY));29 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.ANY));30 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.WINDOWS));31 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.WINDOWS));32 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.MAC));33 caps.add(new DesiredCapabilities("firefox", "3.6", Platform.MAC));34 caps.add(new DesiredCapabilities("firefox", "3.7", Platform.LINUX));
hashCode
Using AI Code Generation
1import org.openqa.selenium.ImmutableCapabilities;2public class HashCode {3 public static void main(String[] args) {4 ImmutableCapabilities cap1 = new ImmutableCapabilities("browserName", "chrome", "platform", "win");5 ImmutableCapabilities cap2 = new ImmutableCapabilities("browserName", "firefox", "platform", "win");6 System.out.println("Hashcode of cap1 is: " + cap1.hashCode());7 System.out.println("Hashcode of cap2 is: " + cap2.hashCode());8 }9}
hashCode
Using AI Code Generation
1public class ImmutableCapabilities extends BaseCapabilities {2 private final Map<String, ?> capabilities;3 public ImmutableCapabilities() {4 this(new HashMap<String, Object>());5 }6 public ImmutableCapabilities(Map<String, ?> capabilities) {7 this.capabilities = new HashMap<String, Object>(capabilities);8 }9 public ImmutableCapabilities(String key, Object value) {10 this();11 capabilities.put(key, value);12 }13 public ImmutableCapabilities(Capabilities capabilities) {14 this(capabilities.asMap());15 }16 public ImmutableCapabilities setCapability(String key, Object value) {17 capabilities.put(key, value);18 return this;19 }20 public ImmutableCapabilities setCapability(CapabilityType capabilityType, Object value) {21 capabilities.put(capabilityType.getCapability(), value);22 return this;23 }24 public ImmutableCapabilities merge(Capabilities extraCapabilities) {25 if (extraCapabilities == null) {26 return this;27 }28 Map<String, Object> newCapabilities = new HashMap<String, Object>(capabilities);29 newCapabilities.putAll(extraCapabilities.asMap());30 return new ImmutableCapabilities(newCapabilities);31 }32 public ImmutableCapabilities merge(Map<String, ?> extraCapabilities) {33 if (extraCapabilities == null) {34 return this;35 }36 Map<String, Object> newCapabilities = new HashMap<String, Object>(capabilities);37 newCapabilities.putAll(extraCapabilities);38 return new ImmutableCapabilities(newCapabilities);39 }40 public Object getCapability(String capabilityName) {41 return capabilities.get(capabilityName);42 }43 public boolean is(String capabilityName) {44 Object capability = capabilities.get(capabilityName);45 if (capability == null) {46 return false;47 }48 if (capability instanceof Boolean) {49 return (Boolean) capability;50 }51 return Boolean.parseBoolean(capability.toString());52 }53 public boolean is(CapabilityType capabilityType) {54 return is(capabilityType.getCapability());55 }56 public ImmutableCapabilities copy() {57 return new ImmutableCapabilities(this);58 }59 public Map<String, ?> asMap() {60 return Collections.unmodifiableMap(capabilities);61 }62 public int hashCode() {63 return capabilities.hashCode();64 }65 public boolean equals(Object obj) {66 if (obj
hashCode
Using AI Code Generation
1public int hashCode() {2 return Objects.hash(browserName, browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy, setWindowRect, timeouts, unhandledPromptBehavior);3}4public int hashCode() {5 return Objects.hash(browserName, browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy, setWindowRect, timeouts, unhandledPromptBehavior);6}7public int hashCode() {8 return Objects.hash(browserName, browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy, setWindowRect, timeouts, unhandledPromptBehavior);9}10public int hashCode() {11 return Objects.hash(browserName, browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy, setWindowRect, timeouts, unhandledPromptBehavior);12}13public int hashCode() {14 return Objects.hash(browserName, browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy, setWindowRect, timeouts, unhandledPromptBehavior);15}16public int hashCode() {17 return Objects.hash(browserName, browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy, setWindowRect, timeouts, unhandledPromptBehavior);18}19public int hashCode() {20 return Objects.hash(browserName, browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy, setWindowRect, timeouts, unhandledPromptBehavior);21}22public int hashCode() {23 return Objects.hash(browserName, browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy, setWindowRect, timeouts, unhandledPromptBehavior);
hashCode
Using AI Code Generation
1import org.openqa.selenium.ImmutableCapabilities;2import java.util.Arrays;3import java.util.Set;4import java.util.HashSet;5{6 public static void main(String[] args)7 {8 ImmutableCapabilities cap1 = new ImmutableCapabilities("browserName", "chrome");9 ImmutableCapabilities cap2 = new ImmutableCapabilities("browserName", "chrome");10 ImmutableCapabilities cap3 = new ImmutableCapabilities("browserName", "firefox");11 ImmutableCapabilities cap4 = new ImmutableCapabilities("browserName", "firefox");12 Set<ImmutableCapabilities> capabilities = new HashSet<ImmutableCapabilities>(Arrays.asList(cap1, cap2, cap3, cap4));13 System.out.println(capabilities.size());14 System.out.println(capabilities.contains(cap1));15 System.out.println(capabilities.contains(cap2));16 System.out.println(capabilities.contains(cap3));17 System.out.println(capabilities.contains(cap4));18 }19}
hashCode
Using AI Code Generation
1public void testHashCode(){2 ImmutableCapabilities cap = new ImmutableCapabilities("platform", "Windows 10", "browserName", "Chrome");3 System.out.println(cap.hashCode());4}5public void testToString(){6 ImmutableCapabilities cap = new ImmutableCapabilities("platform", "Windows 10", "browserName", "Chrome");7 System.out.println(cap.toString());8}9public void testEquals(){10 ImmutableCapabilities cap1 = new ImmutableCapabilities("platform", "Windows 10", "browserName", "Chrome");11 ImmutableCapabilities cap2 = new ImmutableCapabilities("platform", "Windows 10", "browserName", "Chrome");12 System.out.println(cap1.equals(cap2));13}14public void testGetCapability(){15 ImmutableCapabilities cap = new ImmutableCapabilities("platform", "Windows 10", "browserName", "Chrome");16 System.out.println(cap.getCapability("platform"));17}18public void testGetCapabilityNames(){19 ImmutableCapabilities cap = new ImmutableCapabilities("platform", "Windows 10", "browserName", "Chrome");20 Set<String> set = cap.getCapabilityNames();21 for(String s: set){22 System.out.println(s);23 }24}25public void testAsMap(){26 ImmutableCapabilities cap = new ImmutableCapabilities("platform", "Windows 10", "browserName", "Chrome");27 Map<String, Object> map = cap.asMap();28 for(Map.Entry<String, Object> entry: map.entrySet()){29 System.out.println(entry.getKey() + " " + entry.getValue());30 }31}32public void testMerge(){33 ImmutableCapabilities cap1 = new ImmutableCapabilities("platform",
LambdaTest’s Selenium 4 tutorial is covering every aspects of Selenium 4 testing with examples and best practices. Here you will learn basics, such as how to upgrade from Selenium 3 to Selenium 4, to some advanced concepts, such as Relative locators and Selenium Grid 4 for Distributed testing. Also will learn new features of Selenium 4, such as capturing screenshots of specific elements, opening a new tab or window on the browser, and new protocol adoptions.
Upgrading From Selenium 3 To Selenium 4?: In this chapter, learn in detail how to update Selenium 3 to Selenium 4 for Java binding. Also, learn how to upgrade while using different build tools such as Maven or Gradle and get comprehensive guidance for upgrading Selenium.
What’s New In Selenium 4 & What’s Being Deprecated? : Get all information about new implementations in Selenium 4, such as W3S protocol adaption, Optimized Selenium Grid, and Enhanced Selenium IDE. Also, learn what is deprecated for Selenium 4, such as DesiredCapabilites and FindsBy methods, etc.
Selenium 4 With Python: Selenium supports all major languages, such as Python, C#, Ruby, and JavaScript. In this chapter, learn how to install Selenium 4 for Python and the features of Python in Selenium 4, such as Relative locators, Browser manipulation, and Chrom DevTool protocol.
Selenium 4 Is Now W3C Compliant: JSON Wireframe protocol is retiring from Selenium 4, and they are adopting W3C protocol to learn in detail about the advantages and impact of these changes.
How To Use Selenium 4 Relative Locator? : Selenium 4 came with new features such as Relative Locators that allow constructing locators with reference and easily located constructors nearby. Get to know its different use cases with examples.
Selenium Grid 4 Tutorial For Distributed Testing: Selenium Grid 4 allows you to perform tests over different browsers, OS, and device combinations. It also enables parallel execution browser testing, reads up on various features of Selenium Grid 4 and how to download it, and runs a test on Selenium Grid 4 with best practices.
Selenium Video Tutorials: Binge on video tutorials on Selenium by industry experts to get step-by-step direction from automating basic to complex test scenarios with Selenium.
LambdaTest also provides certification for Selenium testing to accelerate your career in Selenium automation testing.
Get 100 minutes of automation test minutes FREE!!