text:
namespace {

// The timeout used to disconnect a client from the IPC Server channel if it
// forgets to do so.  This ensures the server channel is not blocked forever.
const int kInitialRequestTimeoutSeconds = 5;

// This value represents the amount of time to wait for a gnubby request from
// the client before terminating the connection.
const int kGnubbyRequestTimeoutSeconds = 60;

}  // namespace

namespace remoting {

// Creates an IPC server channel which services IPC clients that want to start
// a security key forwarding session.  Once an IPC Client connects to the
// server, the GnubbyAuthHandlerWin class will create a new
// RemoteSecurityKeyIpcServer instance that will service that request.  The new
// instance will exist for the lifetime of the security key request and will be
// assigned a unique IPC channel name and connection id.  The channel name is
// sent to the client which should disconnect the IPC server channel and
// connect to the security key forwarding session IPC channel to send/receive
// security key messages.  The IPC server channel will then be reset so it can
// can service the next client/request.  This system allows multiple security
// key forwarding sessions to occur concurrently.
// TODO(joedow): Update GnubbyAuthHandler impls to run on a separate IO thread
//               instead of the thread it was created on: crbug.com/591739
class GnubbyAuthHandlerWin : public GnubbyAuthHandler, public IPC::Listener {
 public:
  GnubbyAuthHandlerWin();
  ~GnubbyAuthHandlerWin() override;

 private:
  typedef std::map<int, std::unique_ptr<RemoteSecurityKeyIpcServer>>
      ActiveChannels;

  // GnubbyAuthHandler interface.
  void CreateGnubbyConnection() override;
  bool IsValidConnectionId(int gnubby_connection_id) const override;
  void SendClientResponse(int gnubby_connection_id,
                          const std::string& response) override;
  void SendErrorAndCloseConnection(int gnubby_connection_id) override;
  void SetSendMessageCallback(const SendMessageCallback& callback) override;
  size_t GetActiveConnectionCountForTest() const override;
  void SetRequestTimeoutForTest(base::TimeDelta timeout) override;

  // IPC::Listener implementation.
  bool OnMessageReceived(const IPC::Message& message) override;
  void OnChannelConnected(int32_t peer_pid) override;
  void OnChannelError() override;

  // Creates the IPC server channel and waits for a connection using
  // |ipc_server_channel_name_|.
  void StartIpcServerChannel();

  // Restarts the IPC server channel to prepare for another connection.
  void RecreateIpcServerChannel();

  // Closes the IPC channel created for a security key forwarding session.
  void CloseSecurityKeyRequestIpcChannel(int connection_id);

  // Returns the IPC Channel instance created for |connection_id|.
  ActiveChannels::const_iterator GetChannelForConnectionId(
      int connection_id) const;

  // Creates a unique name based on the well-known IPC channel name.
  std::string GenerateUniqueChannelName();

  // Represents the last id assigned to a new security key request IPC channel.
  int last_connection_id_ = 0;

  // Sends a gnubby extension messages to the remote client when called.
  SendMessageCallback send_message_callback_;

  // Tracks the IPC channel created for each security key forwarding session.
  ActiveChannels active_channels_;

  // The amount of time to wait for a client to process the connection details
  // message and disconnect from the IPC server channel before disconnecting it.
  base::TimeDelta disconnect_timeout_;

  // Used to recreate the IPC server channel if a client forgets to disconnect.
  base::OneShotTimer timer_;

  // IPC Clients connect to this channel first to receive their own IPC
  // channel to start a security key forwarding session on.
  std::unique_ptr<IPC::Channel> ipc_server_channel_;

  // Ensures GnubbyAuthHandlerWin methods are called on the same thread.
  base::ThreadChecker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(GnubbyAuthHandlerWin);
};

std::unique_ptr<GnubbyAuthHandler> GnubbyAuthHandler::Create(
    const SendMessageCallback& callback) {
  std::unique_ptr<GnubbyAuthHandler> auth_handler(new GnubbyAuthHandlerWin());
  auth_handler->SetSendMessageCallback(callback);
  return auth_handler;
}

GnubbyAuthHandlerWin::GnubbyAuthHandlerWin()
    : disconnect_timeout_(
          base::TimeDelta::FromSeconds(kInitialRequestTimeoutSeconds)) {}

GnubbyAuthHandlerWin::~GnubbyAuthHandlerWin() {}

void GnubbyAuthHandlerWin::CreateGnubbyConnection() {
  DCHECK(thread_checker_.CalledOnValidThread());
  StartIpcServerChannel();
}

bool GnubbyAuthHandlerWin::IsValidConnectionId(int connection_id) const {
  DCHECK(thread_checker_.CalledOnValidThread());
  return (GetChannelForConnectionId(connection_id) != active_channels_.end());
}

void GnubbyAuthHandlerWin::SendClientResponse(
    int connection_id,
    const std::string& response_data) {
  DCHECK(thread_checker_.CalledOnValidThread());

  ActiveChannels::const_iterator iter =
      GetChannelForConnectionId(connection_id);
  if (iter == active_channels_.end()) {
    HOST_LOG << "Invalid gnubby connection ID received: " << connection_id;
    return;
  }

  if (!iter->second->SendResponse(response_data)) {
    CloseSecurityKeyRequestIpcChannel(connection_id);
  }
}

void GnubbyAuthHandlerWin::SendErrorAndCloseConnection(int connection_id) {
  DCHECK(thread_checker_.CalledOnValidThread());

  SendClientResponse(connection_id, kRemoteSecurityKeyConnectionError);
  CloseSecurityKeyRequestIpcChannel(connection_id);
}

void GnubbyAuthHandlerWin::SetSendMessageCallback(
    const SendMessageCallback& callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  send_message_callback_ = callback;
}

size_t GnubbyAuthHandlerWin::GetActiveConnectionCountForTest() const {
  return active_channels_.size();
}

void GnubbyAuthHandlerWin::SetRequestTimeoutForTest(base::TimeDelta timeout) {
  disconnect_timeout_ = timeout;
}

void GnubbyAuthHandlerWin::StartIpcServerChannel() {
  DCHECK(thread_checker_.CalledOnValidThread());

  // Create a named pipe owned by the current user (the LocalService account
  // (SID: S-1-5-19) when running in the network process) which is available to
  // all authenticated users.
  // presubmit: allow wstring
  std::wstring user_sid;
  CHECK(base::win::GetUserSidString(&user_sid));
  std::string user_sid_utf8 = base::WideToUTF8(user_sid);
  std::string security_descriptor = base::StringPrintf(
      "O:%sG:%sD:(A;;GA;;;AU)", user_sid_utf8.c_str(), user_sid_utf8.c_str());

  base::win::ScopedHandle pipe;
  CHECK(CreateIpcChannel(remoting::GetRemoteSecurityKeyIpcChannelName(),
                         security_descriptor, &pipe));
  ipc_server_channel_ =
      IPC::Channel::CreateNamedServer(IPC::ChannelHandle(pipe.Get()), this);
  CHECK(ipc_server_channel_->Connect());
}

void GnubbyAuthHandlerWin::RecreateIpcServerChannel() {
  DCHECK(thread_checker_.CalledOnValidThread());

  timer_.Stop();
  ipc_server_channel_.reset();

  StartIpcServerChannel();
}

void GnubbyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel(
    int connection_id) {
  active_channels_.erase(connection_id);
}

GnubbyAuthHandlerWin::ActiveChannels::const_iterator
GnubbyAuthHandlerWin::GetChannelForConnectionId(int connection_id) const {
  return active_channels_.find(connection_id);
}

std::string GnubbyAuthHandlerWin::GenerateUniqueChannelName() {
  return GetRemoteSecurityKeyIpcChannelName() + "." +
         IPC::Channel::GenerateUniqueRandomChannelID();
}

bool GnubbyAuthHandlerWin::OnMessageReceived(const IPC::Message& message) {
  DCHECK(thread_checker_.CalledOnValidThread());
  // This class does handle any IPC messages sent by the client.
  return false;
}

void GnubbyAuthHandlerWin::OnChannelConnected(int32_t peer_pid) {
  DCHECK(thread_checker_.CalledOnValidThread());

  timer_.Start(FROM_HERE, disconnect_timeout_,
               base::Bind(&GnubbyAuthHandlerWin::OnChannelError,
                          base::Unretained(this)));

  // TODO(joedow): Use |peer_pid| to determine the originating session
  // using ProcessIdToSessionId() and verify it is the one we created.
  // Tracked via crbug.com/591746

  int new_connection_id = ++last_connection_id_;
  std::unique_ptr<RemoteSecurityKeyIpcServer> ipc_server(
      RemoteSecurityKeyIpcServer::Create(
          new_connection_id, disconnect_timeout_, send_message_callback_,
          base::Bind(&GnubbyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel,
                     base::Unretained(this), new_connection_id)));

  std::string unique_channel_name = GenerateUniqueChannelName();
  if (ipc_server->CreateChannel(
          unique_channel_name,
          base::TimeDelta::FromSeconds(kGnubbyRequestTimeoutSeconds))) {
    active_channels_[new_connection_id] = std::move(ipc_server);
    ipc_server_channel_->Send(
        new ChromotingNetworkToRemoteSecurityKeyMsg_ConnectionDetails(
            unique_channel_name));
  }
}

void GnubbyAuthHandlerWin::OnChannelError() {
  DCHECK(thread_checker_.CalledOnValidThread());

  // Could be an error, most likely the client disconnected though.  Either way
  // we should restart the server to prepare for the next connection.
  RecreateIpcServerChannel();
}

}  // namespace remoting


text:
package org.mpisws.p2p.testing.transportlayer.peerreview;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.X509Certificate;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;

import org.mpisws.p2p.pki.x509.CATool;
import org.mpisws.p2p.pki.x509.CAToolImpl;
import org.mpisws.p2p.pki.x509.X509Serializer;
import org.mpisws.p2p.pki.x509.X509SerializerImpl;
import org.mpisws.p2p.transport.ErrorHandler;
import org.mpisws.p2p.transport.MessageCallback;
import org.mpisws.p2p.transport.MessageRequestHandle;
import org.mpisws.p2p.transport.P2PSocket;
import org.mpisws.p2p.transport.SocketCallback;
import org.mpisws.p2p.transport.SocketRequestHandle;
import org.mpisws.p2p.transport.TransportLayer;
import org.mpisws.p2p.transport.TransportLayerCallback;
import org.mpisws.p2p.transport.peerreview.IdentifierExtractor;
import org.mpisws.p2p.transport.peerreview.PeerReview;
import org.mpisws.p2p.transport.peerreview.PeerReviewCallback;
import org.mpisws.p2p.transport.peerreview.PeerReviewImpl;
import org.mpisws.p2p.transport.peerreview.WitnessListener;
import org.mpisws.p2p.transport.peerreview.commitment.Authenticator;
import org.mpisws.p2p.transport.peerreview.commitment.AuthenticatorSerializer;
import org.mpisws.p2p.transport.peerreview.commitment.AuthenticatorSerializerImpl;
import org.mpisws.p2p.transport.peerreview.commitment.AuthenticatorStore;
import org.mpisws.p2p.transport.peerreview.commitment.CommitmentProtocol;
import org.mpisws.p2p.transport.peerreview.commitment.CommitmentProtocolImpl;
import org.mpisws.p2p.transport.peerreview.evidence.EvidenceSerializerImpl;
import org.mpisws.p2p.transport.peerreview.history.HashProvider;
import org.mpisws.p2p.transport.peerreview.history.SecureHistory;
import org.mpisws.p2p.transport.peerreview.history.SecureHistoryFactory;
import org.mpisws.p2p.transport.peerreview.history.SecureHistoryFactoryImpl;
import org.mpisws.p2p.transport.peerreview.history.hasher.SHA1HashProvider;
import org.mpisws.p2p.transport.peerreview.history.stub.NullHashProvider;
import org.mpisws.p2p.transport.peerreview.identity.IdentityTransport;
import org.mpisws.p2p.transport.peerreview.identity.IdentityTransportCallback;
import org.mpisws.p2p.transport.peerreview.identity.IdentityTransportLayerImpl;
import org.mpisws.p2p.transport.peerreview.identity.UnknownCertificateException;
import org.mpisws.p2p.transport.peerreview.infostore.Evidence;
import org.mpisws.p2p.transport.peerreview.infostore.IdStrTranslator;
import org.mpisws.p2p.transport.peerreview.infostore.PeerInfoStore;
import org.mpisws.p2p.transport.peerreview.infostore.StatusChangeListener;
import org.mpisws.p2p.transport.peerreview.message.PeerReviewMessage;
import org.mpisws.p2p.transport.peerreview.replay.Verifier;
import org.mpisws.p2p.transport.peerreview.replay.record.RecordLayer;
import org.mpisws.p2p.transport.table.UnknownValueException;
import org.mpisws.p2p.transport.util.MessageRequestHandleImpl;
import org.mpisws.p2p.transport.util.Serializer;

import rice.Continuation;
import rice.environment.Environment;
import rice.environment.logging.Logger;
import rice.p2p.commonapi.Cancellable;
import rice.p2p.commonapi.rawserialization.InputBuffer;
import rice.p2p.commonapi.rawserialization.OutputBuffer;
import rice.p2p.commonapi.rawserialization.RawSerializable;
import rice.p2p.util.MathUtils;
import rice.p2p.util.rawserialization.SimpleOutputBuffer;
import rice.selector.TimerTask;

public class PRRegressionTest {
  public static final byte[] EMPTY_ARRAY = new byte[0];
  static class IdExtractor implements IdentifierExtractor<HandleImpl, IdImpl> {

    public IdImpl extractIdentifier(HandleImpl h) {
      return h.id;
    }

  }

  static class HandleSerializer implements Serializer<HandleImpl> {

    public HandleImpl deserialize(InputBuffer buf) throws IOException {
      return HandleImpl.build(buf);
    }

    public void serialize(HandleImpl i, OutputBuffer buf) throws IOException {
      i.serialize(buf);
    }

  }

  static class IdSerializer implements Serializer<IdImpl> {

    public IdImpl deserialize(InputBuffer buf) throws IOException {
      return IdImpl.build(buf);
    }

    public void serialize(IdImpl i, OutputBuffer buf) throws IOException {
      i.serialize(buf);
    }

  }

  static class HandleImpl implements RawSerializable {
    String name;
    IdImpl id;

    public HandleImpl(String s, IdImpl id) {
      this.name = s;
      this.id = id;
    }

    public void serialize(OutputBuffer buf) throws IOException {
      buf.writeUTF(name);
      id.serialize(buf);
    }

    public static HandleImpl build(InputBuffer buf) throws IOException {
      return new HandleImpl(buf.readUTF(), IdImpl.build(buf));
    }

    public String toString() {
      return "HandleImpl<"+name+">";
    }

    public int hashCode() {
      return id.hashCode()^name.hashCode();
    }

    public boolean equals(Object o) {
      HandleImpl that = (HandleImpl)o;
      if (!id.equals(that.id)) return false;
      return name.equals(that.name);
    }
  }

  static class IdImpl implements RawSerializable {
    int id;
    public IdImpl(int id) {
      this.id = id;
    }
    public void serialize(OutputBuffer buf) throws IOException {
      buf.writeInt(id);
    }

    public static IdImpl build(InputBuffer buf) throws IOException {
      return new IdImpl(buf.readInt());
    }

    public String toString() {
      return "Id<"+id+">";
    }

    public int hashCode() {
      return id;
    }

    public boolean equals(Object o) {
      IdImpl that = (IdImpl)o;
      return (this.id == that.id);
    }
  }

  static class BogusTransport implements TransportLayer<HandleImpl, ByteBuffer> {
    public static Map<HandleImpl, BogusTransport> peerTable = new HashMap<HandleImpl, BogusTransport>();

    HandleImpl localIdentifier;
    Environment env;

    public BogusTransport(HandleImpl handle, X509Certificate cert, Environment env) {
      peerTable.put(handle, this);
      this.localIdentifier = handle;
      this.env = env;
    }

    public void acceptMessages(boolean b) {
      throw new RuntimeException("implement");
    }

    public void acceptSockets(boolean b) {
      throw new RuntimeException("implement");
    }

    public HandleImpl getLocalIdentifier() {
      return localIdentifier;
    }

    public SocketRequestHandle<HandleImpl> openSocket(HandleImpl i,
        SocketCallback<HandleImpl> deliverSocketToMe,
        Map<String, Object> options) {
      throw new RuntimeException("implement");
    }

    public MessageRequestHandle<HandleImpl, ByteBuffer> sendMessage(
        HandleImpl i, ByteBuffer m,
        MessageCallback<HandleImpl, ByteBuffer> deliverAckToMe,
        Map<String, Object> options) {
      peerTable.get(i).receiveMessage(localIdentifier, m);
//      if (deliverAckToMe != null) deliverAckToMe.ack(new Message)
      return null;
    }

    TransportLayerCallback<HandleImpl, ByteBuffer> callback;

    private void receiveMessage(final HandleImpl i, final ByteBuffer m) {
//      System.out.println(Thread.currentThread()+" invoking onto "+env.getSelectorManager());
      env.getSelectorManager().invoke(new Runnable() {
        public void run() {
          try {
            callback.messageReceived(i, m, null);
          } catch (IOException ioe) {
            ioe.printStackTrace();
            System.exit(0);
          }
        }
      });
//      System.out.println(Thread.currentThread()+" invoked onto "+env.getSelectorManager());
    }

    public void setCallback(
        TransportLayerCallback<HandleImpl, ByteBuffer> callback) {
      this.callback = callback;
    }

    public void setErrorHandler(ErrorHandler<HandleImpl> handler) {
      throw new RuntimeException("implement");
    }

    public void destroy() {
      throw new RuntimeException("implement");
    }
  }

  class BogusApp implements PeerReviewCallback<HandleImpl, IdImpl> {

    Logger logger;
    Player player;
    Environment env;
    Random rand;
    long nextSendTime = 0;
    private HandleImpl dest;

    private TransportLayer<HandleImpl, ByteBuffer> tl;

    public BogusApp(Player player, TransportLayer<HandleImpl, ByteBuffer> tl, Environment env) {
      super();
      this.player = player;
      this.tl = tl;
      this.env = env;
      this.logger = env.getLogManager().getLogger(BogusApp.class, null);
      logger.log("new bogus app "+player);
      dest = player.destHandle;
      tl.setCallback(this);
    }

    public void init() {
//      logger.log("init()");
      rand = new Random();
      if (player.localHandle.id.id == 1) {
        // need to give the other nodes a second to boot, otherwise this message will go nowhere
        scheduleMessageToBeSent(env.getTimeSource().currentTimeMillis()+1000, true);
      }
    }

    public void scheduleMessageToBeSent() {
      scheduleMessageToBeSent(env.getTimeSource().currentTimeMillis()+rand.nextInt(1999)+1, true);
    }

    public void scheduleMessageToBeSent(long time, final boolean reschedule) {
      nextSendTime = time;
      if (logger.level <= Logger.FINE) logger.log("scheduling message to be sent at:"+time);
      env.getSelectorManager().schedule(new TimerTask() {
        public String toString() {
          return "SendMessageTask "+scheduledExecutionTime();
        }

        @Override
        public void run() {
          sendMessage();
          if (reschedule) scheduleMessageToBeSent();
        }
      }, nextSendTime-env.getTimeSource().currentTimeMillis());
    }

    public void sendMessage() {
      byte[] msg = generateMessage();

      logger.log("sending message "+msg.length+" "+MathUtils.toBase64(msg));
      if (logger.level <= Logger.INFO) logger.log("sending message "+msg.length+" "+MathUtils.toBase64(msg));
//      HandleImpl dest = bob.localHandle;
      try {
      tl.sendMessage(dest, ByteBuffer.wrap(msg), new MessageCallback<HandleImpl, ByteBuffer>() {

        public void sendFailed(MessageRequestHandle<HandleImpl, ByteBuffer> msg,
            Exception reason) {
          logger.log("sendFailed("+msg+")");
//          System.out.println("sendFailed("+msg+")");
//          reason.printStackTrace();
        }

        public void ack(MessageRequestHandle<HandleImpl, ByteBuffer> msg) {
          alice.logger.log("ack("+msg+") "+Thread.currentThread());
          if (logger.level <= Logger.FINE) alice.logger.log("ack("+msg+")");
        }

      }, null);
      } catch (NullPointerException npe) {
        logger.log("tl:"+tl+" "+dest);
        throw npe;
      }
    }

    protected byte[] generateMessage() {
      byte[] msg = new byte[rand.nextInt(31)+1];
      rand.nextBytes(msg);
      return msg;
    }

    public void storeCheckpoint(OutputBuffer buffer) throws IOException {
      if (logger.level <= Logger.FINER) logger.log("storeCheckpoint "+nextSendTime);
      buffer.writeInt(31173);
      buffer.writeLong(nextSendTime);
      buffer.writeBoolean(dest != null);
      if (dest != null) dest.serialize(buffer);
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      new ObjectOutputStream(baos).writeObject(rand);
      byte[] bytes = baos.toByteArray();
      buffer.writeInt(bytes.length);
      buffer.write(bytes, 0, bytes.length);
      if (logger.level <= Logger.FINEST) logger.log("storeCheckpoint:"+Arrays.toString(((SimpleOutputBuffer)buffer).getBytes()));
    }

    public boolean loadCheckpoint(InputBuffer buffer) throws IOException {
      if (buffer.readInt() != 31173) throw new RuntimeException("invalid checkpoint");
      nextSendTime = buffer.readLong();
      if (buffer.readBoolean()) {
        dest = new HandleSerializer().deserialize(buffer);
      }
      if (logger.level <= Logger.FINER) logger.log("loadCheckpoint "+nextSendTime);
      byte[] bytes = new byte[buffer.readInt()];
      buffer.read(bytes);
      ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
      try {
        rand = (Random)new ObjectInputStream(bais).readObject();
      } catch (ClassNotFoundException cnfe) {
        IOException ioe = new IOException("Error reading random number from checkpoint");
        ioe.initCause(cnfe);
        throw ioe;
      }
      if (nextSendTime > 0) {
        scheduleMessageToBeSent(nextSendTime, true);
      }
      return true;
    }

    public void destroy() {
      throw new RuntimeException("implement");
    }

    public void notifyCertificateAvailable(IdImpl id) {
      throw new RuntimeException("implement");
    }

    public void receive(HandleImpl source, boolean datagram, ByteBuffer msg) {
      throw new RuntimeException("implement");
    }

    public void sendComplete(long id) {
      throw new RuntimeException("implement");
    }

    public void incomingSocket(P2PSocket<HandleImpl> s) throws IOException {
      throw new RuntimeException("implement");
    }

    public void messageReceived(HandleImpl i, ByteBuffer m,
        Map<String, Object> options) throws IOException {
      if (logger.level <= Logger.INFO) logger.log("Message received: "+MathUtils.toBase64(m.array()));
    }

    public void getWitnesses(IdImpl subject,
        WitnessListener<HandleImpl, IdImpl> callback) {
      callback.notifyWitnessSet(subject, Collections.singletonList(carol.localHandle));
    }

    public void notifyStatusChange(
        IdImpl id,
        int newStatus) {
      if (logger.level <= Logger.INFO) logger.log("notifyStatusChange("+id+","+PeerReviewImpl.getStatusString(newStatus)+")");
      if (newStatus != STATUS_TRUSTED) {
        logger.log("Failure, Node not trusted: "+id+" at "+player.localHandle);
        System.exit(1);
      }
      addStatusNotification(this.player.localHandle,id,newStatus);
    }

    public Collection<HandleImpl> getMyWitnessedNodes() {
      return player.witnessed;
    }

    public PeerReviewCallback<HandleImpl, IdImpl> getReplayInstance(Verifier<HandleImpl> v) {
      BogusApp ret = new BogusApp(playerTable.get(v.getLocalIdentifier()),v,v.getEnvironment());
      return ret;
    }
  }

  static Map<HandleImpl, IdentityTransportLayerImpl<HandleImpl, IdImpl>> idTLTable = new HashMap<HandleImpl, IdentityTransportLayerImpl<HandleImpl,IdImpl>>();

  CATool caTool;
  KeyPairGenerator keyPairGen;

  Map<HandleImpl,Player> playerTable = new HashMap<HandleImpl, Player>();

  protected PeerReviewImpl<HandleImpl, IdImpl> getPeerReview(Player player, MyIdTL transport, Environment env) {
    return new PeerReviewImpl<HandleImpl, IdImpl>(transport, env, new HandleSerializer(), new IdSerializer(), new IdExtractor(), getIdStrTranslator()
//        ,new AuthenticatorSerializerImpl(20,96), new EvidenceSerializerImpl<HandleImpl, IdImpl>(new HandleSerializer(),new IdSerializer(),transport.getHashSizeBytes(),transport.getSignatureSizeBytes())
        );
  }

  class Player {
    Logger logger;
    HandleImpl localHandle;

    PeerReview<HandleImpl, IdImpl> pr;
    MyIdTL transport;
    public Collection<HandleImpl> witnessed = new ArrayList<HandleImpl>();
    KeyPair pair;
    X509Certificate cert;
    BogusTransport t1;
    Environment env;

//    int id;

    BogusApp app;
    HandleImpl destHandle;

    public Player(HandleImpl localHandle, HandleImpl dstHandle, final Environment env2) throws Exception {
      super();
      this.destHandle = dstHandle;
//      this.id = id;
      env = cloneEnvironment(env2, localHandle.name, localHandle.id.id);

      this.logger = env.getLogManager().getLogger(Player.class, null);

      File f = new File(localHandle.name);
      if (f.exists()) {
        File f2 = new File(f,"peers");
        File[] foo = f2.listFiles();
        if (foo != null) {
          for (int c = 0; c < foo.length; c++) {
            foo[c].delete();
          }
        }

        foo = f.listFiles();
        if (foo != null) {
          for (int c = 0; c < foo.length; c++) {
            foo[c].delete();
          }
        }

//        System.out.println("Delete "+f+","+f.delete());
      }
//      File f = new File(name+".data");
//      if (f.exists()) f.delete();
//      f = new File(name+".index");
//      if (f.exists()) f.delete();

      this.localHandle = localHandle;
      playerTable.put(localHandle, this);

      pair = keyPairGen.generateKeyPair();
      cert = caTool.sign(localHandle.name,pair.getPublic());

      t1 = getTL();

      transport = getIdTransport();

      idTLTable.put(localHandle, transport);
      pr = getPeerReview(this, transport, env);
      app = getApp();
      pr.setApp(app);
      env.getSelectorManager().invoke(new Runnable() {
        public void run() {
          try {
            pr.init(Player.this.localHandle.name);
          } catch (IOException ioe) {
            ioe.printStackTrace();
            env2.destroy();
          }
        }
      });
    }

    public BogusApp getApp() {
      return getBogusApp(this, pr, env);
//      return new BogusApp(this,pr,env);
    }

    // to be overridden
    public Environment cloneEnvironment(Environment env2, String name, int id) {
      return env2.cloneEnvironment(name);
    }

    public void buildPlayerCryptoStuff() {

    }

    public BogusTransport getTL() throws Exception {
      return new BogusTransport(localHandle, cert, env);
    }

    public MyIdTL getIdTransport() throws Exception {
      return new MyIdTL(
          new IdSerializer(), new X509SerializerImpl(),this.localHandle.id,
          cert,pair.getPrivate(),t1,new SHA1HashProvider(),env) {
      };
    }

  }

  public IdStrTranslator<IdImpl> getIdStrTranslator() {
    return new IdStrTranslator<IdImpl>(){

      public IdImpl readIdentifierFromString(String s) {
        return new IdImpl(Integer.parseInt(s));
      }

      public String toString(IdImpl id) {
        return Integer.toString(id.id);
      }};
  }

  class MyIdTL extends IdentityTransportLayerImpl<HandleImpl, IdImpl> {
    public MyIdTL(Serializer<IdImpl> serializer, X509Serializer serializer2,
        IdImpl localId, X509Certificate localCert, PrivateKey localPrivate,
        TransportLayer<HandleImpl, ByteBuffer> tl, HashProvider hasher,
        Environment env) throws InvalidKeyException, NoSuchAlgorithmException,
        NoSuchProviderException {
      super(serializer, serializer2, localId, localCert, localPrivate, tl, hasher,
          env);
    }

    @Override
    public Cancellable requestCertificate(final HandleImpl source, final IdImpl certHolder,
        final Continuation<X509Certificate, Exception> c, Map<String, Object> options) {
      //logger.log("requestCert("+certHolder+" from "+source+")");
      return idTLTable.get(source).requestValue(source, certHolder, new Continuation<X509Certificate, Exception>() {

        public void receiveResult(X509Certificate result) {
          //logger.log("delivering cert for ("+certHolder+") c:"+c);
          knownValues.put(certHolder, result);
          if (c != null) c.receiveResult(result);
        }

        public void receiveException(Exception exception) {
          //logger.logException("exception when requesting cert for ("+certHolder+") c:"+c,exception);
          if (c != null) c.receiveException(exception);
        }

      }, options);
    }
  }

  private HashProvider hasher;
  private SecureHistoryFactory historyFactory;

  Player alice;
  Player bob;
  Player carol;

  HandleImpl aliceHandle = new HandleImpl("alice", new IdImpl(1));
  HandleImpl bobHandle = new HandleImpl("bob", new IdImpl(2));
  HandleImpl carolHandle = new HandleImpl("carol", new IdImpl(3));

  public void setLoggingParams(Environment env) {
    env.getParameters().setInt("org.mpisws.p2p.testing.transportlayer.peerreview_loglevel", Logger.INFO);
//    env.getParameters().setInt("org.mpisws.p2p.transport.peerreview.audit_loglevel", Logger.FINEST);
  }

  protected BogusApp getBogusApp(Player player, PeerReview<HandleImpl, IdImpl> pr,
      Environment env) {
    return new BogusApp(player,pr,env);
  }

  public void buildCryptoMaterial(Environment env) throws Exception {
    SecureRandom random = new SecureRandom();
    caTool = CAToolImpl.getCATool("CommitmentTest","foo".toCharArray());

    // make a KeyPair
    keyPairGen =
      KeyPairGenerator.getInstance("RSA", "BC");
    keyPairGen.initialize(
        new RSAKeyGenParameterSpec(768,
            RSAKeyGenParameterSpec.F4),
        random);
    hasher = new SHA1HashProvider();
    historyFactory = new SecureHistoryFactoryImpl(hasher,env);
  }

  public void buildPlayers(Environment env) throws Exception {
    alice = new Player(aliceHandle, bobHandle, env);
    bob = new Player(bobHandle, aliceHandle, env);
    carol = new Player(carolHandle, null, env);
//    System.out.println("here");
  }

  public void setupWitnesses() {
    carol.witnessed.add(alice.localHandle);
    carol.witnessed.add(bob.localHandle);
  }

  protected Map<HandleImpl, Map<IdImpl, Integer>> recordedStatus = new HashMap<HandleImpl, Map<IdImpl,Integer>>();
  protected void addStatusNotification(HandleImpl localHandle, IdImpl id,
      int newStatus) {
    Map<IdImpl, Integer> foo = recordedStatus.get(localHandle);
    if (foo == null) {
      foo = new HashMap<IdImpl, Integer>();
      recordedStatus.put(localHandle,foo);
    }
    foo.put(id,newStatus);
  }

  public void finish() {
    for (Entry<HandleImpl, Map<IdImpl, Integer>> foo : recordedStatus.entrySet()) {
      for (Entry<IdImpl, Integer> i : foo.getValue().entrySet()) {
        if (i.getValue() != StatusChangeListener.STATUS_TRUSTED) {
          logger.log("Fail: "+foo.getKey()+" found "+i.getKey()+" "+i.getValue());
          System.exit(1);
        }
      }
    }
    logger.log("Success");
    System.exit(1);
  }

  Environment env;
  Logger logger;

  /**
   * @param millisToFinish Call finish() after this amount of time
   * @throws Exception
   */
  public PRRegressionTest(int millisToFinish) throws Exception {

    env = RecordLayer.generateEnvironment(); //new Environment();
    env.getSelectorManager().schedule(new TimerTask() {

      @Override
      public void run() {
        finish();
      }
    },millisToFinish);

    logger = env.getLogManager().getLogger(PRRegressionTest.class, null);
    setLoggingParams(env);

    buildCryptoMaterial(env);

    env.getSelectorManager().invoke(new Runnable() {

      public void run() {
        try {
          buildPlayers(env);

          setupWitnesses();
        } catch (Exception ioe) {
          env.destroy();
          throw new RuntimeException(ioe);
        }
      }
    });
  }

  public static void main(String[] agrs) throws Exception {
    new PRRegressionTest(45000);
  }
}

redpajama_set_name: RedPajamaGithub


text:
package hsup

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"testing"
)

func TestFindsAvailableUIDs(t *testing.T) {
	workDir, err := ioutil.TempDir("", "hsup-libcontainer-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(workDir)
	driver, err := NewLibContainerDynoDriver(workDir)
	if err != nil {
		t.Fatal(err)
	}
	driver.minUID = 1
	driver.maxUID = 3

	// some uids are already allocated...
	if err := createUIDFile(workDir, 1); err != nil {
		t.Fatal(err)
	}
	if err := createUIDFile(workDir, 3); err != nil {
		t.Fatal(err)
	}

	// uid=2 is the only available
	uid, gid, err := driver.findFreeUIDGID()
	if err != nil {
		t.Fatal(err)
	}
	if uid != 2 {
		t.Fatalf("uid=2 was the only available and wasn't allocated. "+
			"Found %d", uid)
	}
	if gid != 2 {
		t.Fatalf("gid=2 was the only available and wasn't allocated. "+
			"Found %d", gid)
	}
	if !checkUIDFile(workDir, 2) {
		t.Fatal("a uid file to lock uid=2 wasn't created")
	}
}

func TestOnlyUsesFreeUIDs(t *testing.T) {
	workDir, err := ioutil.TempDir("", "hsup-libcontainer-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(workDir)
	driver, err := NewLibContainerDynoDriver(workDir)
	if err != nil {
		t.Fatal(err)
	}
	driver.minUID = 3000
	driver.maxUID = 3004

	// some uids are already allocated...
	if err := createUIDFile(workDir, 3002); err != nil {
		t.Fatal(err)
	}
	if err := createUIDFile(workDir, 3003); err != nil {
		t.Fatal(err)
	}

	first, _, err := driver.findFreeUIDGID()
	if err != nil {
		t.Fatal(err)
	}
	if !checkUIDFile(workDir, first) {
		t.Fatalf("a uid file to lock uid=%d wasn't created", first)
	}

	second, _, err := driver.findFreeUIDGID()
	if err != nil {
		t.Fatal(err)
	}
	if !checkUIDFile(workDir, second) {
		t.Fatalf("a uid file to lock uid=%d wasn't created", second)
	}
	if first == second {
		t.Fatalf("allocated uids should not be reused."+
			" Failed %d != %d", first, second)
	}

	third, _, err := driver.findFreeUIDGID()
	if err != nil {
		t.Fatal(err)
	}
	if !checkUIDFile(workDir, third) {
		t.Fatalf("a uid file to lock uid=%d wasn't created", third)
	}
	if first == third || second == third {
		t.Fatalf("allocated uids should not be reused."+
			" Failed %d != %d != %d", first, second, third)
	}
}

func createUIDFile(workDir string, uid int) error {
	f, err := os.Create(filepath.Join(workDir, "uids", strconv.Itoa(uid)))
	if err != nil {
		return err
	}
	return f.Close()
}

func checkUIDFile(workDir string, uid int) bool {
	f, err := os.Open(filepath.Join(workDir, "uids"))
	if err != nil {
		return false
	}
	if err := f.Close(); err != nil {
		return false
	}
	return true
}


text:
<!DOCTYPE html>

<meta http-equiv="content-type" content="text/html;charset=UTF-8" />

	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
  	<meta charset="utf-8" />

	<title>Arduino - Windows </title>
	<link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />

	<link rel="stylesheet" href="../../fonts/fonts.css" type="text/css" />
	<link rel="stylesheet" href="../../css/arduino-icons.css">
	<link rel="stylesheet" href="../../css/animation.css">

	<link rel='stylesheet' href='../../css/foundation2.css' type='text/css' />

	<link rel='stylesheet' href='../../css/arduino_code_highlight.css' type='text/css' />
	<link rel="stylesheet" type="text/css" media="screen" href="../../css/typeplate.css">
	<link rel='stylesheet' href='../pub/skins/arduinoWide_SSO/css/arduinoWide_SSO.css' type='text/css' />

	<link rel='stylesheet' href='../../css/common.css' type='text/css' />
	<link rel="stylesheet" href="../../css/download_page.css" />
	<link href="https://plus.google.com/114839908922424087554" rel="publisher" />

	  <meta name='robots' content='index,follow' />

	<link rel='stylesheet' href='../../../code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.min.css' type='text/css' />

Arduino

				<form method="GET" action="http://www.google.com/search">

		<input type="hidden" name="ie" value="UTF-8">
		<input type="hidden" name="oe" value="UTF-8">
		<input type="text" name="q" size="25" maxlength="255" value="" placeholder="Search the Arduino Website">
		<input type="submit" name="btnG" VALUE="search">
		<input type="hidden" name="domains" value="http://www.arduino.cc">
		<input type="hidden" name="sitesearch" value="http://www.arduino.cc">

</form>

Home

Buy

Download

Products

Arduino (USA only)

Genuino (outside USA)

AtHeart

Certified

Learning

Getting started

Tutorials

Reference

CTC Program

Playground

Forum

Support

FAQ

Contact Us

Blog

LOG IN

SIGN UP

      Getting Started
      > Windows

     English

English

中文 (Chinese)

  </div

Getting Started with Arduino on Windows

This document explains how to connect your Arduino board to the computer and upload your first sketch.

On this page... (hide)

1 | Get an Arduino board and USB cable

2 | Download the Arduino Software (IDE)

3 | Connect the board

4 | Install the drivers

5 | Launch the Arduino application

6 | Open the blink example

7 | Select your board

8 | Select your serial port

9 | Upload the program

1 | Get an Arduino board and USB cable

In this tutorial, we assume you're using an Arduino Uno, Arduino Duemilanove, Nano, Arduino Mega 2560 , or Diecimila.  If you have another board, read the corresponding page in this getting started guide.

You also need a standard USB cable (A plug to B plug): the kind you would connect to a USB printer, for example.  (For the Arduino Nano, you'll need an A to Mini-B cable instead.)

2 | Download the Arduino Software (IDE)

Get the latest version from the download page.
When the download finishes, unzip the downloaded file.

3 | Connect the board

The Arduino Uno, Mega, Duemilanove and Arduino Nano automatically draw power from either the USB connection to the computer or an external power supply.  If you're using an Arduino Diecimila, you'll need to make sure that the board is configured to draw power from the USB connection.  The power source is selected with a jumper, a small piece of plastic that fits onto two of the three pins between the USB and power jacks.  Check that it's on the two pins closest to the USB port.

Connect the Arduino board to your computer using the USB cable.  The green power LED (labelled PWR) should go on.

4 | Install the drivers

Installing drivers for the Arduino Uno or Arduino Mega 2560 with Windows 7, Vista, or XP:

Plug in your board and wait for Windows to begin it's driver installation process.  After a few moments, the process will fail, despite its best efforts

Click on the Start Menu, and open up the Control Panel.

While in the Control Panel, navigate to System and Security. Next, click on System. Once the System window is up, open the Device Manager.

Look under Ports (COM & LPT). You should see an open port named "Arduino UNO (COMxx)".  If there is no COM & LPT section, look under "Other Devices" for "Unknown Device".

Right click on the "Arduino UNO (COmxx)" port and choose the "Update Driver Software" option.

Next, choose the "Browse my computer for Driver software" option.

Finally, navigate to and select the driver file named "arduino.inf", located in the "Drivers" folder of the Arduino Software download (not the "FTDI USB Drivers" sub-directory). If you are using an old version of the IDE (1.0.3 or older), choose the Uno driver file named "Arduino UNO.inf"

Windows will finish up the driver installation from there.

See also: step-by-step screenshots for installing the Uno under Windows XP.

Installing drivers for the Arduino Duemilanove, Nano, or Diecimila with Windows7, Vista, or XP:

When you connect the board, Windows should initiate the driver installation process (if you haven't used the computer with an Arduino board before).

On Windows Vista, the driver should be automatically downloaded and installed.  (Really, it works!)

On Windows XP, the Add New Hardware wizard will open:

When asked Can Windows connect to Windows Update to search for software? select No, not this time.  Click next.

Select Install from  a list or specified location (Advanced) and click next.

Make sure that Search for the best driver in these locations is checked; uncheck Search removable media; check Include this location in the search and browse to the drivers/FTDI USB Drivers directory of the Arduino distribution.  (The latest version of the drivers can be found on the FTDI website.) Click next.

The wizard will search for the driver and then tell you that a "USB Serial Converter" was found.  Click finish.

The new hardware wizard will appear again.  Go through the same steps and select the same options and location to search.  This time, a "USB Serial Port" will be found.

You can check that the drivers have been installed by opening the Windows Device Mananger (in the Hardware tab of System control panel).  Look for a "USB Serial Port" in the Ports section; that's the Arduino board.

5 | Launch the Arduino application

Double-click the Arduino application (arduino.exe) you have previously downloaded .  (Note: if the Arduino Software loads in the wrong language, you can change it in the preferences dialog.  See the Arduino Software (IDE) page for details.)

6 | Open the blink example

Open the LED blink example sketch: File  > Examples >01.Basics > Blink.

7 | Select your board

You'll need to select the entry in the Tools > Board menu that corresponds to your Arduino.

Selecting an Arduino Uno

For Duemilanove Arduino boards with an ATmega328 (check the text on the chip on the board), select Arduino Duemilanove or Nano w/ ATmega328.  Previously, Arduino boards came with an ATmega168; for those, select Arduino Diecimila, Duemilanove, or Nano w/ ATmega168.  (Details of the board menu entries are available on the environment page.)

8 | Select your serial port

Select the serial device of the Arduino board from the Tools | Serial Port menu.  This is likely to be COM3 or higher (COM1 and COM2 are usually reserved for hardware serial ports).  To find out, you can disconnect your Arduino board and re-open the menu; the entry that disappears should be the Arduino board.  Reconnect the board and select that serial port.

9 | Upload the program

Now, simply click the "Upload" button in the environment.  Wait a few seconds - you should see the RX and TX leds on the board flashing.  If the upload is successful, the message "Done uploading." will appear in the status bar.  (Note: If you have an Arduino Mini, NG, or other board, you'll need to physically press the reset button on the board immediately before clicking the upload button on the Arduino Software.)

A few seconds after the upload finishes, you should see the pin 13 (L) LED on the board start to blink (in orange).  If it does, congratulations!  You've gotten Arduino up-and-running. If you have problems, please see the troubleshooting suggestions.

You might also want to look at:

the examples for using various sensors and actuators

the reference for the Arduino language

The text of the Arduino getting started guide is licensed under a
Creative Commons Attribution-ShareAlike 3.0 License.  Code samples in the guide are released into the public domain.

Share

  <form action="http://www.arduino.cc/subscribe.php" method="post" name="sendy-subscribe-form" id="sendy-subscribe-form" class="form-popup">

This link has expired.
Please re-subscribe to our Newsletters.

Subscribe to our Newsletters

            Email

            <input placeholder="Enter your email address" type="email" name="email" class="subscribe-form-input" />

Please enter a valid email to subscribe

            <input style="display:none" type="checkbox" checked name="list[]" value="arduino_newsletter_id" id="worldwide" class="newsletter-form-checkbox" />

Arduino Newsletter

            <input style="display:none" type="checkbox" checked name="list[]" value="arduino_store_newsletter_id" id="store" class="newsletter-form-checkbox" />

Arduino Store Newsletter

          <button type="button" value="Cancel" class="popup-form-button white cancel-modal close-reveal-modal">Cancel</button>
          <button type="submit" name="Subscribe" id="subscribe-submit-btn" class="popup-form-button">Next</button>

  </form>

Confirm your email address

          We need to confirm your email address.

          To complete the subscription, please click the link in the
          email we just sent you.

          Thank you for subscribing!

          Arduino

          via Egeo 16

          Torino, 10131

          Italy

          <button name="Ok" class="popup-form-button" id="close-confirm-popup">Ok</button>

Newsletter

          <input type="email" name="email" class="email" id="sendy-EMAIL" placeholder="Enter your email to sign up">

          <input value="Subscribe" name="subscribe" id="sendy-subscribe" class="newsletter-button">

©2015 Arduino

Copyright Notice

Contact us

About us

Careers

<meta http-equiv="content-type" content="text/html;charset=UTF-8" />


text:
// nonport.cpp            see license.txt for copyright and terms of use
// code for nonport.h
// Scott McPeak and Dan Bonachea, 1998-1999  This file is public domain.

#include <stdio.h>       // printf
#include <stdlib.h>      // abort, exit
#include <string.h>      // strncpy

#ifdef __WIN32__
#  ifdef USE_MINWIN_H
#    include "minwin.h"   // api
#  else
#    include <windows.h>  // api
#  endif

#  include <conio.h>      // getch or _getch
#  include <dos.h>        // sleep
#  include <io.h>         // chmod
#  ifdef __BORLANDC__
#    include <dir.h>      // mkdir, chdir
#    pragma warn -par     // warning: parameter not used
#  else    // MSVC
#    include <errno.h> // ENOENT
#    include <direct.h>   // _mkdir, _chdir
#    define getch _getch
#    define mkdir _mkdir    // why must VC be such an oddball?
#    define chdir _chdir
#    define chmod _chmod
     void sleep(unsigned sec) {
       Sleep(sec * 1000);
       return;
       }
#  endif
#  define DIRSLASH '\\'
#  define DIRSLASHES "\\/"

#else   // unix
#  include <sys/time.h>   // struct timeval, gettimeofday
#  include <sys/types.h>  // mkdir constants, DIR, struct dirent
#  include <fcntl.h>      // mkdir constants
#  include <unistd.h>     // mkdir, sleep, chdir, geteuid
#  include <errno.h>      // errno
#  include <pwd.h>        // getpwuid, struct passwd
#  define DIRSLASH '/'
#  define DIRSLASHES "/"

#endif

#include <sys/stat.h>     // chmod, mode macros
#include <time.h>         // tzset, localtime, time
#include <iostream.h>     // cout

#if !defined(__WIN32__) || defined(__BORLANDC__)
  #include <dirent.h>       // opendir
#endif

#include "nonport.h"      // this module

NonportFailFunc nonportFail = defaultNonportFail;

void defaultNonportFail(char const *, char const *)
{}

// convenience
inline void fail(char const *call, char const *ctx=NULL)
{
  nonportFail(call, ctx);
}

void setRawMode(bool raw)
{
# ifdef __WIN32__
    // nothing necessary; getConsoleChar handles it

# else
    int res;
    if (raw) {
      // turn off UNIX term output, put in raw mode
      res = system("stty -echo raw");
    }
    else {
      // back to normal mode
      res = system("stty echo -raw");
    }

    if (res != 0) {
      //fail("system", "setRawMode");
    }
# endif
}

// get the next character typed, without any intervening interpretation
// or buffering
char getConsoleChar()
{
# ifdef __WIN32__
    // this function always bypasses 'cooked' console mode
    return (char)getch();

# else
    // relies on raw mode for console
    int ch = getchar();
    if (ch == EOF) {
      fail("getchar", "getConsoleChar");
    }
    return ch;
# endif
}

// return the # of milliseconds since some unspecified, but
// constant for the life of the program, event
long getMilliseconds()
{
# ifdef __WIN32__
    // # of milliseconds since program started
    return GetTickCount();

# else
    // some unspecified millisecond count (unspecified
    // because tv.tv_sec * 1000 will overflow a 32-bit
    // long, for typical values)
    struct timeval tv;
    gettimeofday(&tv, NULL);
      // according to HPUX man page, this always returns 0 and does
      // not have any errors defined

    //printf("tv.tv_sec = %d, tv.tv_usec = %d\n",
    //       tv.tv_sec, tv.tv_usec);
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
# endif
}

bool limitFileAccess(char const *fname)
{
  // read/write for user, nothing for group or others
  if (chmod(fname, 0600) != 0) {
    fail("chmod", fname);
    return false;
  }
  else {
    return true;
  }
}

bool createDirectory(char const *dirname)
{
  int res;
# ifdef __WIN32__
    // no 'mode' argument
    res = mkdir(dirname);
# else   // unix
    // read/write/execute permission for user, no one else
    res = mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR);
# endif

  if (res != 0) {
    fail("mkdir", dirname);
    return false;
  }
  else {
    return true;
  }
}

bool changeDirectory(char const *dirname)
{
  if (0!=chdir(dirname)) {
    fail("chdir", dirname);
    return false;
  }
  else {
    return true;
  }
}

bool getCurrentDirectory(char *dirname, int len)
{
  bool ok = getcwd(dirname, len) != NULL;
  if (!ok) {
    fail("getcwd");
  }
  return ok;
}

bool removeFile(char const *fname)
{
  bool ok = unlink(fname) == 0;
  if (!ok) {
    fail("unlink", fname);
  }
  return ok;
}

// this may in fact use a portable subset of the standard
// C library.. but I'm not holding my breath, so that's why
// this routine is in the 'nonport' module
void getCurrentDate(int &month, int &day, int &year)
{
  // tzset is apparently required (recommended?) before
  // calling localtime()
  #if !defined(__CYGWIN__)
  tzset();
  #endif

  // retrieve standard UNIX time
  time_t unixTime;
  time(&unixTime);

  // convert to month/day/year
  struct tm *t = localtime(&unixTime);

  // write into return variables
  month = t->tm_mon + 1;
  day = t->tm_mday;
  year = t->tm_year + 1900;    // this is not a y2k bug!
}

void portableSleep(unsigned seconds)
{
  // with proper headers included (above), "sleep" works
  sleep(seconds);
}

void getCurrentUsername(char *buf, int buflen)
{
  #ifdef __WIN32__
    DWORD len = buflen;
    if (!GetUserName(buf, &len)) {
      fail("GetUserName");
      strncpy(buf, "(unknown)", buflen);
    }

  #else    // unix (SunOS only?  we'll see..)
    #if 0     // old.. linux man page insists 'cuserid' is a bad fn to call
      char temp[L_cuserid];
      cuserid(temp);         // fail return?
    #endif // 0

    char const *temp;
    struct passwd *pw = getpwuid(geteuid());
    if (!pw) {
      fail("getpwuid(geteuid())");
      temp = "(unknown)";
    }
    else {
      temp = pw->pw_name;
    }

    strncpy(buf, temp, buflen);
  #endif
}

// loop reading characters, return when finished
static void nonechoLoop(char *buf, int len)
{
  int cursor = 0;
  for(;;) {
    char ch = getConsoleChar();
    switch (ch) {
      case '\r':    // carriage return
        buf[cursor] = 0;
        return;

      case '\b':    // backspace
        if (cursor > 0) {
          cursor--;
        }
        break;

      default:
        buf[cursor++] = ch;
        if (cursor >= len-1) {
          // end of buffer
          buf[len-1] = 0;
          return;
        }
        break;
    }
  }
}

void readNonechoString(char *buf, int len, char const *prompt)
{
  cout << prompt;
  cout.flush();

  setRawMode(true);

  try {
    nonechoLoop(buf, len);
  }
  catch (...) {
    setRawMode(false);    // make sure it gets reset
    throw;
  }

  setRawMode(false);

  cout << "\n";
  cout.flush();
}

void applyToCwdContents(PerFileFunc func, void *extra)
{
  applyToDirContents(".", func, extra);
}

void applyToDirContents(char const *dirName,
                        PerFileFunc func, void *extra)
{
  // SM: we had find{first,next} code here for win32, but
  //     my Borland has opendir & friends, so let's see if
  //     that works everywhere.. (old code is below, in
  //     trash section)
  // DOB: VC doesn't have opendir-
  //  I think this is the only way to do it in the Win32 API
  #if defined(__WIN32__) && !defined(__BORLANDC__)
    struct _finddata_t fb;
    char* buf = new char[strlen(dirName)+5];
    strcpy(buf, dirName);
    if (buf[strlen(buf)-1] != '\\') strcat(buf, "\\");
    strcat(buf, "*");
    long handle = _findfirst(buf, &fb);
    delete buf;
    int done = (handle == -1);
    if (handle == -1 && errno != ENOENT) // ENOENT = no matching entries
      fail("_findfirst", dirName);
    while (!done) {
      if (!func(fb.name, extra)) {
	break;
	}
      done = _findnext(handle, &fb);
      }
    if (handle != -1) {
      if (_findclose(handle)) fail("_findclose", dirName);
      }

  #else     // unix and borland
    DIR *dir = opendir(dirName);
    if (!dir) {
      fail("opendir", dirName);
      return;
    }

    for(;;) {
      // grab next directory entry
      struct dirent *ent = readdir(dir);
      if (!ent) {
	break;     // end of listing
      }

      if (!func(ent->d_name, extra)) {
	break;     // user wants to stop listing
      }
    }

    if (closedir(dir) != 0) {
      fail("closedir", dirName);
    }
  #endif
}

bool isDirectory(char const *path)
{
  struct stat st;
  if (0!=stat(path, &st)) {
    fail("stat", path);
    return false;
  }
  #if defined(__WIN32__) && !defined(__BORLANDC__)
    return !!(st.st_mode & _S_IFDIR); // this is how it works for VC
  #else
    return S_ISDIR(st.st_mode);
  #endif
}

bool fileOrDirectoryExists(char const *path)
{
  struct stat st;
  if (0!=stat(path, &st)) {
    return false;     // assume error is because of nonexistence
  }
  else {
    return true;
  }
}

// adapted from Dan's keyutils.cpp (and indentation style
// ruthlessly changed! :) )
bool ensurePath(char const *filename, bool isDirectory)
{
  // make a temporary buffer so we can modify it safely
  int len = strlen(filename);
  char *temp = new char[len+1];
  strcpy(temp, filename);

  if (isDirectory) {
    len++;    // also consider final '\0' (strchr returns ptr to it)
  }

  // start at 1 (and not 0) because if the path starts with a slash,
  // then starting at 0 will cause us to try mkdir("")
  for (int i=1; i < len; i++) {
    if (strchr(DIRSLASHES, temp[i])) {
      // wherever there is a slash (or '\0'), truncate and test
      temp[i] = '\0';
      if (!fileOrDirectoryExists(temp)) {
        // make directory if necessary; automatically limits file access
        if (!createDirectory(temp)) {
          delete[] temp;
          return false;
        }
      }
      temp[i] = DIRSLASH;      // may kill final '\0', doesn't matter
    }
  }

  // was leaking this.. found the leak with the feudal-C instrumentor!
  delete[] temp;
  return true;
}

// underlying test
bool hsrcHelper()
{
  #if !defined(__WIN32__)     // unix
    // see if /dev/random exists and is readable
    int fd = open("/dev/random", O_RDONLY);
    if (fd < 0) {
      return false;
    }

    // looks ok!
    if (close(fd) < 0) {
      perror("close");
      return false;      // seems unlikely, but..
    }

    return true;

  #else    // windows
    return false;
  #endif
}

bool hasSystemCryptoRandom()
{
  static bool cached = false;
  static bool cachedAnswer;

  if (!cached) {
    cachedAnswer = hsrcHelper();
    cached = true;
  }

  return cachedAnswer;
}

// assume we are only called if the above fn returned true;
// for this fn, any failure is considered fatal because we
// don't have a way to communicate it, and the possibility of
// returning nonrandom values is not tolerable (if something
// I haven't thought of is causing failure, add it to the list
// of things hasSystemCryptoRandom checks)
unsigned getSystemCryptoRandom()
{
  #if !defined(__WIN32__)     // unix
    // open /dev/random
    int fd = open("/dev/random", O_RDONLY);
    if (!fd) {
      perror("open");
      exit(2);
    }

    // grab 4 bytes
    union {
      unsigned ret;
      char c[4];
    };
    int got = 0;

    while (got < 4) {
      int ct = read(fd, c+got, 4-got);
      if (ct < 0) {
       	perror("read");
       	exit(2);
      }
      if (ct == 0) {
        fprintf(stderr, "got 0 bytes from /dev/random.. it's supposed to block!!\n");
        exit(2);
      }
      got += ct;
    }

    if (close(fd) < 0) {
      perror("close");
      exit(2);
    }

    return ret;

  #else     // windows
    fprintf(stderr, "no system crypto random function available!\n");
    exit(2);
    return 0;    // silence warning
  #endif
}

int getProcessId()
{
  #ifdef __WIN32__
    return GetCurrentProcessId();

  #else  // unix
    return getpid();

  #endif
}

// do we have access to C99 vsnprintf?
#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
  #if __GLIBC__ >= 3 || (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)
    // glibc-2.1 or later: yes (glibc-2.0.6 has a function called
    // vsnprintf, but the interface is wrong)
    #define HAS_C99_VSNPRINTF
  #endif
#endif

// note to reader: if your system has C99 VSNPRINTF, feel free to add
// appropriate detection code

#ifndef HAS_C99_VSNPRINTF
  // no vsnprintf, will use gprintf (which is slow, and overestimates sometimes)
  #include "gprintf.h"        // general_vprintf

  static int counting_output_function(void *extra, int ch)
  {
    // 'extra' is a pointer to the count
    int *ct = (int*)extra;
    (*ct)++;
    return 0;    // no failure
  }
#endif // !HAS_C99_VSNPRINTF

int vnprintf(char const *format, va_list args)
{
  #ifdef HAS_C99_VSNPRINTF
    // can use this directly
    return vsnprintf(NULL, 0, format, args);

  #else
    // conservatively interpret the format string using gprintf
    int count = 0;
    general_vprintf(counting_output_function, &count, format, args);
    return count;
  #endif
}

int nprintf(char const *format, ...)
{
  va_list args;
  va_start(args, format);
  int ret = vnprintf(format, args);
  va_end(args);
  return ret;
}

// ----------------- test code --------------------
#ifdef TEST_NONPORT

#include <stdio.h>       // printf

// helper for testing applyToCwdFiles
bool printFirst10(char const *name, void *extra)
{
  int &count = *((int*)extra);
  count++;
  if (count <= 10) {
    printf("  %s\n", name);
    return true;    // continue
  }
  else {
    return false;   // stop
  }
}

bool printIt(char const *name, void*)
{
  printf("%s\n", name);
  return true;    // continue
}

void testingFail(char const *call, char const *ctx)
{
  printf("FAIL: call=%s, ctx=%s, errno=%d\n",
         call, (ctx? ctx : "(null)"), errno);
}

void nprintfVector(char const *format, ...)
{
  va_list args;

  // run vnprintf to obtain estimate
  va_start(args, format);
  int est = vnprintf(format, args);
  va_end(args);

  // make that much space
  char *buf = new char[est+1 + 50 /*safety margin*/];

  // run the real vsprintf
  va_start(args, format);
  int len = vsprintf(buf, format, args);
  va_end(args);

  if (len > est) {
    printf("nprintf failed to conservatively estimate!\n");
    printf("    format: %s\n", format);
    printf("  estimate: %d\n", est);
    printf("    actual: %d\n", len);
    exit(2);
  }

  if (len != est) {
    // print the overestimates; they shouldn't be much noise in the
    // common case, but might hint at a problem earlier than I'd
    // otherwise notice
    printf("nprintf overestimate:\n");
    printf("    format: %s\n", format);
    printf("  estimate: %d\n", est);
    printf("    actual: %d\n", len);
  }

  delete[] buf;
}

int main(int argc, char **argv)
{
  nonportFail = testingFail;

  char s[4];
  s[0] = '-';
  s[1] = 'l';
  s[2] = 's';
  s[3] = 0;
  if (0!=strcmp(s, "-ls")) {
    printf("strcmp failed!\n");
    return 4;
  }

  // process arguments
  bool interactive = false;
  for (int i=1; i<argc; i++) {
    if (0==strcmp("-ls", argv[i])) {
      // do an ls, and bail
      applyToCwdContents(printIt);
      return 0;
    }
    else if (0==strcmp("-noninteractive", argv[i])) {
      // don't do the interactive stuff
      interactive = false;
    }
    else {
      printf("unknown option: %s\n", argv[i]);
      return 2;
    }
  }

  // trying to figure out why backspace sometimes gives ^? crap
  // (turns out Konsole sometimes sends ^? in response to BS,
  // even when the option looks unchecked)
  //char buf[80];
  //printf("type stuff and try backspace: ");
  //gets(buf);
  //printf("%s (%d chars)\n", buf, strlen(buf));
  //return 0;

  long startTime = getMilliseconds();

  if (interactive) {
    printf("Type some characters; you should see each\n"
	   "character echoed once as you type it (q to stop):\n");
    setRawMode(true);
    char ch;
    do {
      ch = getConsoleChar();
      printf("%c", ch);
    } while (ch != 'q');

    setRawMode(false);

    printf("\n\nYou typed for %ld milliseconds\n",
	   getMilliseconds() - startTime);
  }

  limitFileAccess("chmod.test");

  printf("if the current dir contains a file called "
         "chmod.test, I just attempted to limit\n"
         "its access to just the owner\n");

  createDirectory("test.dir");

  // test chdir, which also implicitly tests mkdir
  bool didFirst=false;
  if (!changeDirectory("test.dir") || (didFirst=true, false) ||
      !changeDirectory("..")) {
    printf("failed while trying to chdir to %s\n",
           (didFirst? ".." : "test.dir"));
  }

  // more straightforward
  if (!fileOrDirectoryExists("test.dir")) {
    printf("test.dir didn't get created?\n");
  }

  printf("what's more, I just tried to mkdir & chdir test.dir\n");

  // test ensurePath
  if (!ensurePath("test.dir/a/b/c/d", false /*isDirectory*/)) {
    printf("ensurePath test.dir/a/b/c/d failed\n");
  }

  // try to list partial directory contents
  printf("listing of first 10 files in this directory:\n");
  {
    int count = 0;
    applyToCwdContents(printFirst10, &count);
  }

  // test date function
  {
    int m, d, y;
    getCurrentDate(m, d, y);

    printf("I think the date is (m/d/yyyy): %d/%d/%d\n",
           m, d, y);
  }

  // test sleep (mostly just to make sure it doesn't segfault)
  printf("sleeping for 1 second...\n");
  portableSleep(1);

  // test user name
  char buf[80];
  getCurrentUsername(buf, 80);
  printf("current user name is: %s\n", buf);

  if (interactive) {
    // test nonecho reading
    printf("Type something and press Enter; it won't be echoed (yet):\n");
    readNonechoString(buf, 80, "  > ");
    printf("You typed: %s\n", buf);
  }

  // test random stuff
  printf("hasSystemCryptoRandom: ");
  if (!hasSystemCryptoRandom()) {
    printf("no\n");
  }
  else {
    printf("yes\n");

    printf("three random numbers: %u %u %u\n",
           getSystemCryptoRandom(),
           getSystemCryptoRandom(),
           getSystemCryptoRandom());
  }

  printf("testing nprintf...\n");
  nprintfVector("simple");
  nprintfVector("a %s more", "little");
  nprintfVector("some %4d more %s complicated %c stuff",
                33, "yikes", 'f');
  nprintfVector("%f", 3.4);

  printf("nonport works\n");
  return 0;
}

#endif // TEST_NONPORT

// -------------- trash ----------------
#if 0
void limitFileAccess(char const *fname)
{
  // we'll decide whether this is possible by whether
  // or not the necessary macros are defined
#ifndef S_IRGRP     // assume rest are if this is
    // probably can't do anything
    return;
#else

  // modify file permissions (to simplify things,
  // we'll just set permissions, rather than
  // read-modify-write); don't bother testing for
  // error condition since there isn't much we
  // can do about it anyway
  chmod(fname, S_IRUSR | S_IWUSR);
# endif
}

# ifdef __WIN32__     // findfirst, findnext
#   ifdef __BORLANDC__
      struct ffblk fb;
      int done = findfirst("*", &fb, 0);
      while (!done) {
        if (!func(fb.ff_name, extra)) {
          break;
        }
        done = findnext(&fb);
      }
#   else  // DOB: VC has a totally diff interface for this
      struct _finddata_t fb;
      long handle = _findfirst("*", &fb);
      int done = (handle == -1);
      while (!done) {
        if (!func(fb.name, extra)) {
          break;
        }
        done = _findnext(handle, &fb);
      }
      if (handle != -1) _findclose(handle);
#   endif
# else    // unix     // {open,read,close}dir, stat
# endif

#endif // 0    (trash)


text:
import { set } from '@ember/object';
import { test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { init, globals, renderDefault } from '../../../helpers/tree-node';

init();

test('shows text', function(assert) {
  assert.expect(1);

  renderDefault.call(this);

  assert.strictEqual(this.$('.text').text().trim(), 'test-text');
});

test('shows default loading text', function(assert) {
  assert.expect(1);

  set(this, 'loadingText', undefined);

  renderDefault.call(this, false);

  this.$('.toggle').click();

  assert.strictEqual(this.$('.loading').text().trim(), 'loading...');
});

test('shows custom loading text', function(assert) {
  assert.expect(1);

  renderDefault.call(this, false);

  this.$('.toggle').click();

  assert.strictEqual(this.$('.loading').text().trim(), 'test-loading');
});

test('doesn\'t send action when started open', function(assert) {
  assert.expect(1);

  let done = assert.async();

  set(this, 'model.isOpen', true);

  let calledCount = 0;

  this.on('toggleChanged', isOpen => {
    calledCount++;

    if (!isOpen) {
      assert.strictEqual(calledCount, 1);

      done();
    }
  });

  renderDefault.call(this);

  this.$('.toggle').click();
});

test('has no content by default', function(assert) {
  assert.expect(1);

  renderDefault.call(this);

  assert.strictEqual(this.$('.children').text().trim(), '');
});

test('has content rendered when clicked once', function(assert) {
  assert.expect(1);

  renderDefault.call(this);

  this.$('.toggle').click();

  assert.strictEqual(this.$('.children').text().trim(), 'test-child');
});

test('has no content when clicked twice', function(assert) {
  assert.expect(1);

  renderDefault.call(this);

  this.$('.toggle').click();
  this.$('.toggle').click();

  assert.strictEqual(this.$('.children').text().trim(), '');
});

test('sends model on toggle changed', function(assert) {
  assert.expect(1);

  let done = assert.async();

  this.on('toggleChanged', (isOpen, model) => {
    assert.strictEqual(model.text, 'test-text');

    done();
  });

  renderDefault.call(this);

  this.$('.toggle').click();
});

test('sends model on open', function(assert) {
  assert.expect(1);

  let done = assert.async();

  this.on('opened', model => {
    assert.strictEqual(model.text, 'test-text');

    done();
  });

  renderDefault.call(this);

  this.$('.toggle').click();
});

test('sends model on close', function(assert) {
  assert.expect(1);

  let done = assert.async();

  this.on('closed', model => {
    assert.strictEqual(model.text, 'test-text');

    done();
  });

  renderDefault.call(this);

  this.$('.toggle').click();
  this.$('.toggle').click();
});

test('sends model on selection changed', function(assert) {
  assert.expect(1);

  let done = assert.async();

  this.on('selectionChanged', (isSelected, model) => {
    assert.strictEqual(model.text, 'test-text');

    done();
  });

  renderDefault.call(this);

  this.$('input').click();
});

test('sends model on selected', function(assert) {
  assert.expect(1);

  let done = assert.async();

  this.on('selected', model => {
    assert.strictEqual(model.text, 'test-text');

    done();
  });

  renderDefault.call(this);

  this.$('input').click();
});

test('sends model on unselected', function(assert) {
  assert.expect(1);

  let done = assert.async();

  this.on('unselected', model => {
    assert.strictEqual(model.text, 'test-text');

    done();
  });

  renderDefault.call(this);

  this.$('input').click();
  this.$('input').click();
});

test('doesn\'t load children before toggle', function(assert) {
  assert.expect(1);

  renderDefault.call(this, false);

  assert.notOk(globals.wasChildrenCalled);
});

test('preserves toggle open in children when parent closes', function(assert) {
  assert.expect(1);

  this.render(hbs`
    {{#tree-node
      (hash
        children=(array null)
      )
      id="parent"
      handleToggleInternally=true
    }}
      {{tree-node
        model
        id="child"
        handleToggleInternally=true
      }}
    {{/tree-node}}
  `);

  this.$('#parent .toggle:first').click();

  this.$('#child .toggle').click();

  this.$('#parent .toggle:first').click();
  this.$('#parent .toggle:first').click();

  assert.strictEqual(this.$('#child .open').length, 1);
});


text:
We have created a user on OpenShift Red Hat and gave the namespace 'coderstage'
Then we created a new application: Jenkins Server.

OpenShift URL --> https://openshift.redhat.com/app/console/applications
Jenkins URL   --> http://jenkins-coderstage.rhcloud.com/
How to Manage Apps in the Cloud with Command Line Tool (RHC) --> https://blog.openshift.com/using-rhc-to-manage-paas-apps/


text:
//Pseudocode
/*
Create objects, Hero, Weapon, Enemy

Equip Function -
Input: Weapon object, hero object
Output: Hero's weapon property changed
Steps: IF the hero and the item are at the same place, return weapon property TRUE.

Punch/Kick Function -
Input: hero object and enemy object
Output: Damage done to the enemy
Steps: subtract 'some' enemy health where 'some' is equal to the damage property of the hero

Weapon Function -
Input: Hero object and Weapon object
Output: changed damage of hero
Steps: IF hero has a weapon THEN
hero damage should be set equal to the weapon's damage

Remove a Class/ Add a Class Function(s) -
Input: ID string for HTML div, HTML class name string
Output: Either no class, or a new class
Steps: Access the HTML div and set the class name to either nothing or to a new class name

Arrow Keys -
Input: User keyboard presses
Output: An animation
Steps:
IF ctrl key is pressed THEN
kick punching bag
damage the punching bag
change the class so that the animation kicks too
ELSE IF alt key is pressed THEN
punch the punching bag
damage the punching bag
change the class so that the animation punches too
ELSE IF z is pressed THEN
weapon hit on the punching bag
damage the punching bag
change the class so that the animation hits the bag
ELSE IF left arrow key is pressed THEN
walk left animiation
ELSE IF right arrow key is pressed THEN
walk right animation
ENDIF

*/

//Stick Fighter - Prototype

// 1st establish objects - hero(s), weapon(s), enemy(s)?
// The Hero - A Stick Figure
var hero = {
	health: 100,
	damage: {
		hand: 5,
		foot: 10
	},
	weapon: false,
	pos: {
		x: 0,
		y: 0
	}
}

// The Enemy - A Punching Bag
var punchingBag = {
	health: 1000,
	pos: {
		x: 0,
		y: 0
	}
}

// The Weapon - A Sword
var sword = {
	damage: {
		hand: 15,
		special: 30
	},
	weapon: true,
	pos: {
		x: 0,
		y: 0
	}
}

// Function to equip a sword and increase damage
function equip(item, person){
	if (item.pos == person.pos)
		person.damage.hand = item.damage.hand;
		person.weapon = item.weapon;
}

// Function to punch an enemy if the enemy is in the same place
function punch(person, enemy){
	if (enemy.pos === hero.pos)
		enemy.health -= person.damage.hand;
}

// Function to kick an enemy
function kick(person, enemy){
	if (enemy.pos === person.pos)
		enemy.health -= person.damage.foot;
}

// Function to use a weapon's special traits
function weapon(person, enemy){
	if (person.weapon === true){
		if (enemy.pos === person.pos){
			enemy.health -= person.damage.special;
		} else {
			person.health -= 1;
		}
	} else {
		// Alert that there is no weapon equipped
		console.log("You have no weapon equipped.")
	}
}

// Functions for adding and removing a class - for CSS animations
function removeAclass(idString, classString) {
	var id = idString;
	var myClassName = classString;
	var thing;
	thing = document.getElementById(id);
	thing.className = thing.className.replace(myClassName, "")
}

function addAclass(idString, classString) {
	var id = idString;
	var myClassName = classString;
	var thing;
	thing = document.getElementById(id);
	thing.className = thing.className.replace(myClassName, "");
	thing.className = thing.className + myClassName;
}

// Health Bar JavaScript and Damage
function damage(health,htmlid,damage) {
	health = document.getElementById(htmlid);
	health.value = health.value - damage;
};

// recognizing the arrow key presses
document.onkeydown = function(e) {
    switch (e.keyCode) {
        case 37:
            //alert('left');
           	//hero = document.getElementById('hero');
            //hero.style.left = (hero.style.left.replace('px','')*1)-5;
            addAclass('hero', 'walkleft');
            setInterval(function() { removeAclass('hero', 'walkleft'); }, 1500);
            break;
        case 38:
            //alert('up');
            break;
        case 39:
            //alert('right');
          	//hero = document.getElementById('hero');
            //hero.style.left = (hero.style.left.replace('px','')*1)+5;
            addAclass('hero', 'walkright');
            setInterval(function() { removeAclass('hero', 'walkright'); }, 1500);
            break;
        case 40:
        	//alert('down');
        	break;
        case 17:
        	addAclass('hero', 'kick');
        	setInterval(function() { removeAclass('hero', 'kick'); }, 1500);
        	kick(hero, punchingBag);
        	damage(punchingBag.health, 'healthEnemy', hero.damage.foot);
        	addAclass('punchingBag','swing');
        	setInterval(function() { removeAclass('punchingBag', 'swing'); }, 1500);
        	break;
    	case 18:
    		addAclass('hero', 'punch');
			setInterval(function() { removeAclass('hero', 'punch'); }, 1500);
    		punch(hero, punchingBag);
    		damage(punchingBag.health, 'healthEnemy', hero.damage.hand);
    		addAclass('punchingBag','swing');
        	setInterval(function() { removeAclass('punchingBag', 'swing'); }, 1500);
    		break;
		case 90:
			//alert('z');
			addAclass('hero', 'sword');
			setInterval(function() { removeAclass('hero', 'sword'); }, 1500);
			weapon(hero, punchingBag);
			damage(punchingBag.health, 'healthEnemy', hero.damage.hand);
			addAclass('punchingBag','swing');
        	setInterval(function() { removeAclass('punchingBag', 'swing'); }, 1500);
			break;
    }
};

/*
Reflection

What was the most difficult part of this challenge?

Keeping it small. I also wanted to get the animation to move across the screen but without
JQuery, it got to be too hard. I think staying focused on the functions that I did make
was important. Also drawing the images was difficult for me as I'm not artistic in that way.

What did you learn about creating objects and functions that interact with one another?

I learned that it is important to keep all my names straight and be careful that I spell
it properly. Additionally, I got better at creating multiple functions that interact with
each other.

Did you learn about any new built-in methods you could use in your refactored solution? If so, what were they and how do they work?

Not for this one. I did learn that I would like to be able to use JQuery. It would have
saved me a lot of headached when adding and removing classes.

How can you access and manipulate properties of objects?

Using the dot syntax or the square brackets syntax. E.g. either object.property or
object["property"] would acces the properties of the objects. Then they can be manipulated
like variables (basic arithmetic).

*/