Merge "services/repository,services/application/applicationd: make Put like PutX"
diff --git a/services/application/application/impl_test.go b/services/application/application/impl_test.go
index 1a6b8bd..aff8d72 100644
--- a/services/application/application/impl_test.go
+++ b/services/application/application/impl_test.go
@@ -91,8 +91,9 @@
 	return envelope, nil
 }
 
-func (s *server) Put(ctx *context.T, _ rpc.ServerCall, profiles []string, env application.Envelope) error {
-	ctx.VI(2).Infof("%v.Put(%v, %v) was called", s.suffix, profiles, env)
+func (s *server) Put(ctx *context.T, _ rpc.ServerCall, profile string, env application.Envelope, overwrite bool) error {
+	ctx.VI(2).Infof("%v.Put(%v, %v, %t) was called", s.suffix, profile, env, overwrite)
+	fmt.Fprintf(&serverOut, "Put(%s, ..., %t)\n", profile, overwrite)
 	return nil
 }
 
diff --git a/services/application/applicationd/impl_test.go b/services/application/applicationd/impl_test.go
index e7a3be9..4f49d7f 100644
--- a/services/application/applicationd/impl_test.go
+++ b/services/application/applicationd/impl_test.go
@@ -127,17 +127,17 @@
 	}
 	checkNoProfile(t, ctx, stub)
 
-	// Test PutX(), adding a number of application envelopes.
-	if err := stubV1.PutX(ctx, "base", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	// Test Put(), adding a number of application envelopes.
+	if err := stubV1.Put(ctx, "base", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
-	if err := stubV1.PutX(ctx, "media", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV1.Put(ctx, "media", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
-	if err := stubV2.PutX(ctx, "base", envelopeV2, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV2.Put(ctx, "base", envelopeV2, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
-	if err := stub.PutX(ctx, "base", envelopeV1, false); err == nil || verror.ErrorID(err) != appd.ErrInvalidSuffix.ID {
+	if err := stub.Put(ctx, "base", envelopeV1, false); err == nil || verror.ErrorID(err) != appd.ErrInvalidSuffix.ID {
 		t.Fatalf("Unexpected error: expected %v, got %v", appd.ErrInvalidSuffix, err)
 	}
 
@@ -161,8 +161,8 @@
 
 	// Test that if we add another envelope for a version that's the highest
 	// in sort order, the new envelope becomes the latest.
-	if err := stubV3.PutX(ctx, "base", envelopeV3, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV3.Put(ctx, "base", envelopeV3, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 	checkEnvelope(t, ctx, envelopeV3, stub, "base", "media")
 	checkProfiles(t, ctx, stubV3, "base")
@@ -177,8 +177,8 @@
 		},
 		Publisher: blessings,
 	}
-	if err := stubV0.PutX(ctx, "base", envelopeV0, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV0.Put(ctx, "base", envelopeV0, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 	checkEnvelope(t, ctx, envelopeV3, stub, "base", "media")
 
@@ -199,14 +199,14 @@
 		t.Errorf("unexpected Glob results. Got %q, want %q", matches, expected)
 	}
 
-	// PutX cannot replace the envelope for v0-base when overwrite is false.
-	if err := stubV0.PutX(ctx, "base", envelopeV2, false); err == nil || verror.ErrorID(err) != verror.ErrExist.ID {
+	// Put cannot replace the envelope for v0-base when overwrite is false.
+	if err := stubV0.Put(ctx, "base", envelopeV2, false); err == nil || verror.ErrorID(err) != verror.ErrExist.ID {
 		t.Fatalf("Unexpected error: expected %v, got %v", appd.ErrInvalidSuffix, err)
 	}
 	checkEnvelope(t, ctx, envelopeV0, stubV0, "base")
-	// PutX can replace the envelope for v0-base when overwrite is true.
-	if err := stubV0.PutX(ctx, "base", envelopeV2, true); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	// Put can replace the envelope for v0-base when overwrite is true.
+	if err := stubV0.Put(ctx, "base", envelopeV2, true); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 	checkEnvelope(t, ctx, envelopeV2, stubV0, "base")
 
@@ -246,20 +246,20 @@
 	checkNoEnvelope(t, ctx, stubV1, "media")
 	checkNoEnvelope(t, ctx, stubV2, "base")
 
-	if err := stubV0.PutX(ctx, "base", envelopeV0, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV0.Put(ctx, "base", envelopeV0, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
-	if err := stubV1.PutX(ctx, "base", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV1.Put(ctx, "base", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
-	if err := stubV1.PutX(ctx, "media", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV1.Put(ctx, "media", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
-	if err := stubV2.PutX(ctx, "base", envelopeV2, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV2.Put(ctx, "base", envelopeV2, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
-	if err := stubV3.PutX(ctx, "base", envelopeV3, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV3.Put(ctx, "base", envelopeV3, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 	if err := stub.Remove(ctx, "*"); err != nil {
 		t.Fatalf("Remove() failed: %v", err)
@@ -313,8 +313,8 @@
 		Publisher: blessings,
 	}
 
-	if err := stubV1.PutX(ctx, "media", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubV1.Put(ctx, "media", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 
 	// There is content here now.
@@ -468,8 +468,8 @@
 	// Test that we can add an envelope for v3 with profile media and after calling
 	// TidyNow(), there will be all versions still in glob but v0 will only match profile
 	// base and not have an envelope for profile media.
-	if err := stubs[3].PutX(ctx, "media", envelopeV3, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := stubs[3].Put(ctx, "media", envelopeV3, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 
 	if err := stubs[0].TidyNow(ctx); err != nil {
@@ -538,8 +538,8 @@
 func stuffEnvelopes(t *testing.T, ctx *context.T, stubs []repository.ApplicationClientStub, pets []profEnvTuple) {
 	for i, pet := range pets {
 		for _, profile := range pet.p {
-			if err := stubs[i].PutX(ctx, profile, *pet.e, true); err != nil {
-				t.Fatalf("%d: PutX(%v) failed: %v", i, pet, err)
+			if err := stubs[i].Put(ctx, profile, *pet.e, true); err != nil {
+				t.Fatalf("%d: Put(%v) failed: %v", i, pet, err)
 			}
 		}
 	}
diff --git a/services/application/applicationd/perms_test.go b/services/application/applicationd/perms_test.go
index c415b9e..64c1f5f 100644
--- a/services/application/applicationd/perms_test.go
+++ b/services/application/applicationd/perms_test.go
@@ -100,13 +100,13 @@
 	}
 
 	// Envelope putting as other should fail.
-	if err := v1stub.PutX(otherCtx, "base", envelopeV1, false); verror.ErrorID(err) != verror.ErrNoAccess.ID {
-		t.Fatalf("PutX() returned errorid=%v wanted errorid=%v [%v]", verror.ErrorID(err), verror.ErrNoAccess.ID, err)
+	if err := v1stub.Put(otherCtx, "base", envelopeV1, false); verror.ErrorID(err) != verror.ErrNoAccess.ID {
+		t.Fatalf("Put() returned errorid=%v wanted errorid=%v [%v]", verror.ErrorID(err), verror.ErrNoAccess.ID, err)
 	}
 
 	// Envelope putting as global should succeed.
-	if err := v1stub.PutX(ctx, "base", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := v1stub.Put(ctx, "base", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 
 	ctx.VI(2).Infof("Accessing the Permission Lists of the root returns a (simulated) list providing default authorization.")
@@ -157,8 +157,8 @@
 	}
 
 	// Envelope putting as other should now succeed.
-	if err := v1stub.PutX(otherCtx, "base", envelopeV1, true); err != nil {
-		t.Fatalf("PutX() wrongly failed: %v", err)
+	if err := v1stub.Put(otherCtx, "base", envelopeV1, true); err != nil {
+		t.Fatalf("Put() wrongly failed: %v", err)
 	}
 
 	// Other takes control.
@@ -242,16 +242,16 @@
 
 	ctx.VI(2).Info("Upload an envelope")
 	v1stub := repository.ApplicationClient("repo/search/v1")
-	if err := v1stub.PutX(ctx, "base", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := v1stub.Put(ctx, "base", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 	v2stub := repository.ApplicationClient("repo/search/v2")
-	if err := v2stub.PutX(ctx, "base", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := v2stub.Put(ctx, "base", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 	v3stub := repository.ApplicationClient("repo/naps/v1")
-	if err := v3stub.PutX(ctx, "base", envelopeV1, false); err != nil {
-		t.Fatalf("PutX() failed: %v", err)
+	if err := v3stub.Put(ctx, "base", envelopeV1, false); err != nil {
+		t.Fatalf("Put() failed: %v", err)
 	}
 
 	ctx.VI(2).Info("Self can access Permissions but other can't.")
@@ -376,8 +376,8 @@
 
 	// Other can now upload an envelope at both locations.
 	for _, stub := range []repository.ApplicationClientStub{v1stub, v2stub} {
-		if err := stub.PutX(otherCtx, "base", envelopeV1, true); err != nil {
-			t.Fatalf("PutX() failed: %v", err)
+		if err := stub.Put(otherCtx, "base", envelopeV1, true); err != nil {
+			t.Fatalf("Put() failed: %v", err)
 		}
 	}
 
diff --git a/services/application/applicationd/service.go b/services/application/applicationd/service.go
index 0869f13..7d12040 100644
--- a/services/application/applicationd/service.go
+++ b/services/application/applicationd/service.go
@@ -135,55 +135,12 @@
 	return empty, verror.New(verror.ErrNoExist, ctx)
 }
 
-func (i *appRepoService) Put(ctx *context.T, call rpc.ServerCall, profiles []string, envelope application.Envelope) error {
-	ctx.VI(0).Infof("%v.Put(%v, %v)", i.suffix, profiles, envelope)
-	name, version, err := parse(ctx, i.suffix)
-	if err != nil {
-		return err
-	}
-	if version == "" {
-		return verror.New(ErrInvalidSuffix, ctx)
-	}
-	i.store.Lock()
-	defer i.store.Unlock()
-	// Transaction is rooted at "", so tname == tid.
-	tname, err := i.store.BindTransactionRoot("").CreateTransaction(call)
-	if err != nil {
-		return err
-	}
-
-	// Only add a Permissions value if there is not already one present.
-	apath := naming.Join("/acls", name, "data")
-	aobj := i.store.BindObject(apath)
-	if _, err := aobj.Get(call); verror.ErrorID(err) == fs.ErrNotInMemStore.ID {
-		rb, _ := security.RemoteBlessingNames(ctx, call.Security())
-		if len(rb) == 0 {
-			// None of the client's blessings are valid.
-			return verror.New(ErrNotAuthorized, ctx)
-		}
-		newperms := pathperms.PermissionsForBlessings(rb)
-		if _, err := aobj.Put(nil, newperms); err != nil {
-			return err
-		}
-	}
-
-	for _, profile := range profiles {
-		path := naming.Join(tname, "/applications", name, profile, version)
-
-		object := i.store.BindObject(path)
-		_, err := object.Put(call, envelope)
-		if err != nil {
-			return verror.New(ErrOperationFailed, ctx)
-		}
-	}
-	if err := i.store.BindTransaction(tname).Commit(call); err != nil {
-		return verror.New(ErrOperationFailed, ctx)
-	}
-	return nil
+func (i *appRepoService) PutX(ctx *context.T, call rpc.ServerCall, profile string, envelope application.Envelope, overwrite bool) error {
+	return i.Put(ctx, call, profile, envelope, overwrite)
 }
 
-func (i *appRepoService) PutX(ctx *context.T, call rpc.ServerCall, profile string, envelope application.Envelope, overwrite bool) error {
-	ctx.VI(0).Infof("%v.PutX(%v, %v, %t)", i.suffix, profile, envelope, overwrite)
+func (i *appRepoService) Put(ctx *context.T, call rpc.ServerCall, profile string, envelope application.Envelope, overwrite bool) error {
+	ctx.VI(0).Infof("%v.Put(%v, %v, %t)", i.suffix, profile, envelope, overwrite)
 	name, version, err := parse(ctx, i.suffix)
 	if err != nil {
 		return err
diff --git a/services/repository/repository.vdl b/services/repository/repository.vdl
index 3990d3a..2d977c2 100644
--- a/services/repository/repository.vdl
+++ b/services/repository/repository.vdl
@@ -18,17 +18,14 @@
 // envelopes, as well as querying for a list of supported profiles.
 type Application interface {
 	public.Application
-	// DEPRECATED. Please use PutX for new code.
-	// Put adds the given tuple of application version (specified
-	// through the object name suffix) and application envelope to all
-	// of the given application profiles.
-	Put(Profiles []string, Envelope application.Envelope) error {access.Write}
-	// PutX adds the given application envelope for the given profile and
+	// Put adds the given application envelope for the given profile and
 	// application version (required, and specified through the object name
 	// suffix).
 	//
 	// An error is returned if an envelope already exists, unless the
 	// overwrite option is set.
+	Put(Profile string, Envelope application.Envelope, Overwrite bool) error {access.Write}
+	// DEPRECATED. Please use Put for new code.
 	PutX(Profile string, Envelope application.Envelope, Overwrite bool) error {access.Write}
 	// Remove removes the application envelope for the given profile
 	// name and application version (specified through the object name
diff --git a/services/repository/repository.vdl.go b/services/repository/repository.vdl.go
index 65a3890..07c29d2 100644
--- a/services/repository/repository.vdl.go
+++ b/services/repository/repository.vdl.go
@@ -43,17 +43,14 @@
 	//   and executing the "search" application, version "v1", runnable
 	//   on either the "base" or "media" profile.
 	repository.ApplicationClientMethods
-	// DEPRECATED. Please use PutX for new code.
-	// Put adds the given tuple of application version (specified
-	// through the object name suffix) and application envelope to all
-	// of the given application profiles.
-	Put(ctx *context.T, Profiles []string, Envelope application.Envelope, opts ...rpc.CallOpt) error
-	// PutX adds the given application envelope for the given profile and
+	// Put adds the given application envelope for the given profile and
 	// application version (required, and specified through the object name
 	// suffix).
 	//
 	// An error is returned if an envelope already exists, unless the
 	// overwrite option is set.
+	Put(ctx *context.T, Profile string, Envelope application.Envelope, Overwrite bool, opts ...rpc.CallOpt) error
+	// DEPRECATED. Please use Put for new code.
 	PutX(ctx *context.T, Profile string, Envelope application.Envelope, Overwrite bool, opts ...rpc.CallOpt) error
 	// Remove removes the application envelope for the given profile
 	// name and application version (specified through the object name
@@ -89,8 +86,8 @@
 	repository.ApplicationClientStub
 }
 
-func (c implApplicationClientStub) Put(ctx *context.T, i0 []string, i1 application.Envelope, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "Put", []interface{}{i0, i1}, nil, opts...)
+func (c implApplicationClientStub) Put(ctx *context.T, i0 string, i1 application.Envelope, i2 bool, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "Put", []interface{}{i0, i1, i2}, nil, opts...)
 	return
 }
 
@@ -127,17 +124,14 @@
 	//   and executing the "search" application, version "v1", runnable
 	//   on either the "base" or "media" profile.
 	repository.ApplicationServerMethods
-	// DEPRECATED. Please use PutX for new code.
-	// Put adds the given tuple of application version (specified
-	// through the object name suffix) and application envelope to all
-	// of the given application profiles.
-	Put(ctx *context.T, call rpc.ServerCall, Profiles []string, Envelope application.Envelope) error
-	// PutX adds the given application envelope for the given profile and
+	// Put adds the given application envelope for the given profile and
 	// application version (required, and specified through the object name
 	// suffix).
 	//
 	// An error is returned if an envelope already exists, unless the
 	// overwrite option is set.
+	Put(ctx *context.T, call rpc.ServerCall, Profile string, Envelope application.Envelope, Overwrite bool) error
+	// DEPRECATED. Please use Put for new code.
 	PutX(ctx *context.T, call rpc.ServerCall, Profile string, Envelope application.Envelope, Overwrite bool) error
 	// Remove removes the application envelope for the given profile
 	// name and application version (specified through the object name
@@ -193,8 +187,8 @@
 	gs *rpc.GlobState
 }
 
-func (s implApplicationServerStub) Put(ctx *context.T, call rpc.ServerCall, i0 []string, i1 application.Envelope) error {
-	return s.impl.Put(ctx, call, i0, i1)
+func (s implApplicationServerStub) Put(ctx *context.T, call rpc.ServerCall, i0 string, i1 application.Envelope, i2 bool) error {
+	return s.impl.Put(ctx, call, i0, i1, i2)
 }
 
 func (s implApplicationServerStub) PutX(ctx *context.T, call rpc.ServerCall, i0 string, i1 application.Envelope, i2 bool) error {
@@ -231,16 +225,17 @@
 	Methods: []rpc.MethodDesc{
 		{
 			Name: "Put",
-			Doc:  "// DEPRECATED. Please use PutX for new code.\n// Put adds the given tuple of application version (specified\n// through the object name suffix) and application envelope to all\n// of the given application profiles.",
+			Doc:  "// Put adds the given application envelope for the given profile and\n// application version (required, and specified through the object name\n// suffix).\n//\n// An error is returned if an envelope already exists, unless the\n// overwrite option is set.",
 			InArgs: []rpc.ArgDesc{
-				{"Profiles", ``}, // []string
-				{"Envelope", ``}, // application.Envelope
+				{"Profile", ``},   // string
+				{"Envelope", ``},  // application.Envelope
+				{"Overwrite", ``}, // bool
 			},
 			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
 		},
 		{
 			Name: "PutX",
-			Doc:  "// PutX adds the given application envelope for the given profile and\n// application version (required, and specified through the object name\n// suffix).\n//\n// An error is returned if an envelope already exists, unless the\n// overwrite option is set.",
+			Doc:  "// DEPRECATED. Please use Put for new code.",
 			InArgs: []rpc.ArgDesc{
 				{"Profile", ``},   // string
 				{"Envelope", ``},  // application.Envelope